0

最近,我遇到了一个 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 );
}

编辑:我忘了告诉你什么是“项目”变量的类型

4

2 回答 2

1

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

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

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

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

  • 如果第一个表达式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 的评论,因为您正在strcpy()确保container[]为每个字符串分配内存。

我的建议:

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

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

于 2013-03-24T18:00:10.790 回答
0

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”变量,您的问题并不清楚。您的示例代码没有为字符串分配任何内存。

于 2013-03-24T18:39:37.333 回答