简体   繁体   English

C-内存分配问题-需要说明

[英]C - memory allocation issue - need explanation

Recently, I have encountered a problem with C pointers. 最近,我遇到了C指针问题。 As you might see, I've got a loop that reads data from STDIN. 如您所见,我有一个循环从STDIN读取数据。 The problem is I don't quite understand what I've done. 问题是我不太了解自己所做的事情。

I allocated memory for this struct_CONTAINER structure. 我为此struct_CONTAINER结构分配了内存。 I desired to have an array of c-strings with BUFFER_SIZE length inside it. 我希望在其中具有BUFFER_SIZE长度的c字符串数组。 If I understand correctly, this array contains BUFFER_SIZE (char *) objects - and that means that the weight of this array would be 8 * BUFFER_SIZE bytes (8 bytes at most for each char pointer). 如果我理解正确,则此数组包含BUFFER_SIZE(char *)对象-这意味着此数组的权重将为8 * BUFFER_SIZE字节(每个char指针最多8个字节)。 So, for example, if BUFFER_SIZE is defined with value 10, then that gives us 80 bytes for this array and probably the whole structure would have a similar size. 因此,例如,如果将BUFFER_SIZE定义为值10,则该数组的长度为80个字节,整个结构的大小可能相似。

The problem is I am able to iterate over that pointer with values greater than BUFFER_SIZE and what is weird for me - that memory is not NULL. 问题是我可以使用大于BUFFER_SIZE的值遍历该指针,这对我来说很奇怪-内存不是NULL。 I know that in that loop I might be trying to access some other already allocated memory. 我知道在那个循环中我可能正在尝试访问其他一些已经分配的内存。 But I'm not sure. 但是我不确定。 If somebody would be nice and told me what I am doing right and wrong. 如果有人会很好并且告诉我我在做对与错。 It's possible that the memory allocation is too large. 内存分配可能太大。 Thanks in advance! 提前致谢!

char *item = NULL;

if( dup2( STDIN_FILENO, fdin ) < 0 ){
    perror( "dup2(  )" );
    exit( errno );
}

memset( reading, '\0', BUFFER_SIZE );

struct struct_CONTAINER{
    char *container[BUFFER_SIZE];
};


while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    item = &shmemContainer->container[i++];
    strcpy(item, reading);
    memset( reading, '\0', BUFFER_SIZE );
}

EDIT: I forgot to show you what is the type of "item" variable 编辑:我忘了向您展示什么是“ item”变量的类型

Your struct member container is of char* type means its array of strings. 您的struct成员containerchar*类型,表示其字符串数组。 you are assigning to item address of string that char** and try to call strcpy(item, reading); 您正在分配给char**字符串的item地址,并尝试调用strcpy(item, reading);

You are doing wrong at-least in one of following statments. 您在以下其中一项陈述中至少做错了。

 item = &shmemContainer->container[i++];
        ^   is wrong 
 strcpy(item, reading);
         ^ or this is wrong

[ANSWER] ( as you commented first point is error in your code ) [答案]正如您评论的第一点是代码中的错误
Because precedence of -> operator is higher then & . 因为->运算符的优先级比&更高 You should get a warning when you compile your code. 编译代码时,您应该得到警告。

  • if first expression item = &shmemContainer->container[i++]; 如果第一个表达式item = &shmemContainer->container[i++]; is wrong write it like: 写错是这样的:

    item = (&shmemContainer)->container[i++];

  • and if strcpy(item, reading); 并且如果是strcpy(item, reading); is wrong correct it like: 错误是正确的,例如:

    strcpy(*item, reading);

And as I can understand from your while loop you wants to read string from fdin into string array and you can do like: 从您的while循环中可以理解,您想将fdin字符串读取为字符串数组,您可以执行以下操作:

while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    reading[r_control] = '\0'; // null ternimate
    strcpy(shmemContainer->container[i++],reading) ;
    memset( reading, '\0', BUFFER_SIZE );
}

code reading[r_control] = '\\0'; 代码reading[r_control] = '\\0'; added this because first time you are missing memset() , remember read() doesn't terminate \\0 string it self. 添加此内容是因为第一次缺少memset() ,请记住read()不会自行终止\\0字符串。

EDIT : 编辑
Consider @Digikata's comment because you are doing strcpy() to container[] be sure that you allocate memory for each string. 考虑@Digikata的注释,因为您正在对container[]执行strcpy() ,请确保为每个字符串分配内存。

My suggestion: 我的建议:

container[] is array of string so you can allocate memory in your while loop, like: container[]是字符串数组,因此您可以在while循环中分配内存,例如:

i = 0;
while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    reading[r_control] = '\0'; // null ternimate
    shmemContainer->container[i] = malloc(strlen(reading) + 1);
    strcpy(shmemContainer->container[i++],reading) ;
    memset( reading, '\0', BUFFER_SIZE );
}

Added memory allocation if you are missing. 如果丢失,则添加了内存分配。

C doesn't prevent you from indexing past the the intended memory location. C不会阻止您索引超出预期的存储位置。 For example: 例如:

char astring[5] = "0123";  // there is a zero at index 4 
char* ptr = astring;       // ptr[4] == 0

printf("%c", ptr[5]);  // reads a byte beyond the end of the string array 

Your code needs to logically prevent that from occurring, as there is frequently data there, but writing it (and sometimes even reading it) will result in undefined behavior. 您的代码需要从逻辑上防止这种情况的发生,因为那里经常有数据,但是编写(有时甚至是读取)数据将导致不确定的行为。 So in your code, it's normal for the area beyond your container to read as not NULL. 因此,在您的代码中,容器之外的区域读取为非NULL是正常的。

BTW, it's not clear from your question if you understand the difference between a char* type pointing to a c-string and the allocated memory area for example the "ptr" the "astring" variable in the code above. 顺便说一句,目前尚不清楚您是否理解指向​​c字符串的char *类型与分配的内存区域之间的区别,例如,上面代码中的“ ptr”和“ astring”变量。 Your sample code doesn't allocate any memory for the string. 您的示例代码不会为该字符串分配任何内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM