繁体   English   中英

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

[英]C - memory allocation issue - need explanation

最近,我遇到了C指针问题。 如您所见,我有一个循环从STDIN读取数据。 问题是我不太了解自己所做的事情。

我为此struct_CONTAINER结构分配了内存。 我希望在其中具有BUFFER_SIZE长度的c字符串数组。 如果我理解正确,则此数组包含BUFFER_SIZE(char *)对象-这意味着此数组的权重将为8 * BUFFER_SIZE字节(每个char指针最多8个字节)。 因此,例如,如果将BUFFER_SIZE定义为值10,则该数组的长度为80个字节,整个结构的大小可能相似。

问题是我可以使用大于BUFFER_SIZE的值遍历该指针,这对我来说很奇怪-内存不是NULL。 我知道在那个循环中我可能正在尝试访问其他一些已经分配的内存。 但是我不确定。 如果有人会很好并且告诉我我在做对与错。 内存分配可能太大。 提前致谢!

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 );
}

编辑:我忘了向您展示什么是“ item”变量的类型

您的struct成员containerchar*类型,表示其字符串数组。 您正在分配给char**字符串的item地址,并尝试调用strcpy(item, reading);

您在以下其中一项陈述中至少做错了。

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

[答案]正如您评论的第一点是代码中的错误
因为->运算符的优先级比&更高 编译代码时,您应该得到警告。

  • 如果第一个表达式item = &shmemContainer->container[i++]; 写错是这样的:

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

  • 并且如果是strcpy(item, reading); 错误是正确的,例如:

    strcpy(*item, reading);

从您的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 );
}

代码reading[r_control] = '\\0'; 添加此内容是因为第一次缺少memset() ,请记住read()不会自行终止\\0字符串。

编辑
考虑@Digikata的注释,因为您正在对container[]执行strcpy() ,请确保为每个字符串分配内存。

我的建议:

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 );
}

如果丢失,则添加了内存分配。

C不会阻止您索引超出预期的存储位置。 例如:

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 

您的代码需要从逻辑上防止这种情况的发生,因为那里经常有数据,但是编写(有时甚至是读取)数据将导致不确定的行为。 因此,在您的代码中,容器之外的区域读取为非NULL是正常的。

顺便说一句,目前尚不清楚您是否理解指向​​c字符串的char *类型与分配的内存区域之间的区别,例如,上面代码中的“ ptr”和“ astring”变量。 您的示例代码不会为该字符串分配任何内存。

暂无
暂无

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

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