fork数组赋值冲突
Fork array assignment conflict
我有以下内容并尝试逐行读取文件,然后将该行放入数组。
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] = '[=10=]';
}
if (strcmp(line, "History") == 0) {
for(int m = 0; m < history_size; m++) {
printf("%s\n", history[m]);
}
} else {
//printf("....%s\n", line);
history[history_size++] = line;
}
}
fclose(fp);
if (line)
free(line);
问题是数组不收集行,当我 运行 代码打印时 "History" 与文件中的行一样多。我好几天都受不了。历史应该保留历史行之前出现的行。
与fork()
无关。
来自getline
的manpage:
If *lineptr is NULL, then getline() will allocate a buffer for storing the line, which should be freed by the user program. (In this case, the value in *n is ignored.)
If the buffer is not large enough to hold the line, getline() resizes it with realloc(3), updating *lineptr and *n as necessary.
问题是您正在将地址分配给数组元素。最后它们都指向相同的地址(取决于 getline
的 realloc
)。由于您没有 malloc
,因此 getline
必须在内部完成,并且在随后的调用中 realloc
在 getline
内部使用,这通常会保留相同的地址。因此,随着 line
更新的循环,所有数组元素也可能会更新,因为大多数数组元素指向相同的地址。
所以最后当你达到你的 line
是 "History"
的条件时,他们只是显示了 line
包含的内容(即 "History"),因为他们都指向与 line
.
相同的地址
这是问题的主要原因,但是 fork()
肯定会偏离您之后想要的输出方式。尽管 fork()
只会干扰您的输出,并且可以通过在 fork()
返回 0
时不打印来轻松处理。
更正:
1) 正如您在对问题的评论中所说,如果 fork() == 0
,您正在做 execvp()
,它不应该引起问题。您需要做的就是:
history[history_size] = malloc(sizeof(char)* (strlen(line)+1));
strcpy(history[history_size++], line);
而不是直接赋值
2) 记住在每次迭代中 free()
由 line
中的 getline()
分配的内存。
我有以下内容并尝试逐行读取文件,然后将该行放入数组。
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] = '[=10=]';
}
if (strcmp(line, "History") == 0) {
for(int m = 0; m < history_size; m++) {
printf("%s\n", history[m]);
}
} else {
//printf("....%s\n", line);
history[history_size++] = line;
}
}
fclose(fp);
if (line)
free(line);
问题是数组不收集行,当我 运行 代码打印时 "History" 与文件中的行一样多。我好几天都受不了。历史应该保留历史行之前出现的行。
与fork()
无关。
来自getline
的manpage:
If *lineptr is NULL, then getline() will allocate a buffer for storing the line, which should be freed by the user program. (In this case, the value in *n is ignored.)
If the buffer is not large enough to hold the line, getline() resizes it with realloc(3), updating *lineptr and *n as necessary.
问题是您正在将地址分配给数组元素。最后它们都指向相同的地址(取决于 getline
的 realloc
)。由于您没有 malloc
,因此 getline
必须在内部完成,并且在随后的调用中 realloc
在 getline
内部使用,这通常会保留相同的地址。因此,随着 line
更新的循环,所有数组元素也可能会更新,因为大多数数组元素指向相同的地址。
所以最后当你达到你的 line
是 "History"
的条件时,他们只是显示了 line
包含的内容(即 "History"),因为他们都指向与 line
.
这是问题的主要原因,但是 fork()
肯定会偏离您之后想要的输出方式。尽管 fork()
只会干扰您的输出,并且可以通过在 fork()
返回 0
时不打印来轻松处理。
更正:
1) 正如您在对问题的评论中所说,如果 fork() == 0
,您正在做 execvp()
,它不应该引起问题。您需要做的就是:
history[history_size] = malloc(sizeof(char)* (strlen(line)+1));
strcpy(history[history_size++], line);
而不是直接赋值
2) 记住在每次迭代中 free()
由 line
中的 getline()
分配的内存。