C语言 分叉数组分配冲突



我有以下内容,并尝试逐行从文件中读取,然后将该行放入数组中。

char **history = malloc(sizeof(char*) * 1000);
int history_size = 0;
fp = fopen(file, "r");
if (fp == NULL)
exit(EXIT_FAILURE);
while ((read = getline(&line, &len, fp)) != -1) {
if(strstr(line, "n") != NULL) {
line[strlen(line) - 1] = '';
}
if (strcmp(line, "History") == 0) {
for(int m = 0; m < history_size; m++) {
printf("%sn", history[m]);
}
} else {
//printf("....%sn", line);
history[history_size++] = line;
}
}
fclose(fp);
if (line)
free(line);

问题是数组不收集行,当我运行代码时,它打印的"历史记录"与文件中的行一样多。 我好几天都管不了了。历史记录应保留历史记录行之前出现的行。

它与fork()无关。

来自getline的手册页:

如果 *lineptr 为 NULL,则 getline(( 将分配一个缓冲区来存储该行,该缓冲区应由用户程序释放。(在这种情况下,将忽略 *n 中的值。

如果缓冲区不够大,无法容纳该行, getline(( 使用 realloc(3( 调整它的大小, 根据需要更新 *lineptr 和 *n。

问题是您正在将地址分配给数组元素。最后它们都指向同一个地址(取决于getlinerealloc(。由于您没有malloc,因此getline必须在内部执行此操作,并且在后续调用中realloc在内部使用getline通常会保留相同的地址。因此,随着line更新,所有数组元素也可能也会更新,因为大多数数组元素都指向相同的地址。

所以最后当你达到你的line"History"的条件时,他们只是显示line包含的内容(即"历史"(,因为它们都指向与line相同的地址。

这是问题的主要原因,但fork()肯定会偏离您之后想要的输出方式。尽管fork()只会干扰您的输出,并且可以通过在返回0时不打印fork()轻松处理。

修正:

1(正如您在有关问题的评论中所说,您正在做execvp()如果fork() == 0,它应该不会引起问题。您需要做的就是:

history[history_size] = malloc(sizeof(char)* (strlen(line)+1));
strcpy(history[history_size++], line);

而不是直接分配它。

2(请记住在每次迭代中free()getline()分配的内存line.

最新更新