gpt4 book ai didi

c - 为什么使用 char** 会导致 char* 工作时出现段错误?

转载 作者:行者123 更新时间:2023-12-03 03:28:26 25 4
gpt4 key购买 nike

第 1 部分

int main(int argc, char **argv)
{
int fd;
int i;
char *line;

if (!(fd = open(argv[1], O_RDWR | O_CREAT)))
{
printf("Error in open\n");
return (0);
}
while ((i = get_next_line(fd, &line)) > 0)
{
printf("%i-%s\n",i, line);
free(line);
}
printf("%i-%s",i, line);
free(line);
}

第 2 部分

int main(int argc, char **argv)
{
int fd;
int i;
char **line;

if (!(fd = open(argv[1], O_RDWR | O_CREAT)))
{
printf("Error in open\n");
return (0);
}
while ((i = get_next_line(fd, line)) > 0)
{
printf("%i-%s\n",i, *line);
free(*line);
}
printf("%i-%s",i, *line);
free(*line);
}
<小时/>

第1部分和第2部分有什么区别吗?它们之间的区别是一个使用**line,另一个仅使用*line。根据我的理解,两者应该是相同的。

我正在使用它们来测试我自己的读取并返回 1 行的函数的实现。

问题:

第 1 部分测试运行良好。第 2 部分段错误测试结果

两者的 get_next_line() 实现保持相同。

最佳答案

在第一种情况下,使用&line将有效地址传递给get_next_line。但在第二种情况下,使用 line 将未初始化的变量传递给函数。您没有显示 get_next_line 但我认为它会执行类似 *line = blah 的操作,如果传入 line 值,这当然会出现段错误不是一个有效的地址(从技术上讲,取消引用未初始化的指针是未定义的行为,因此它可能会出现段错误,但也可能表现出任何其他行为)。

另一种看待它的方式:

char            **line;
get_next_line(fd, line);
printf("%i-%s\n",i, *line);

这基本上就是第二种情况的作用。我们知道在 C 中函数参数是按值传递的。因此 get_next_line 无法更改调用者的 line 变量的值。因此,当函数返回时,line 的值是未定义的,因为它从未初始化。因此,即使 get_next_line 不取消引用 lineprintf 仍然会导致未定义的行为,因为它取消引用 line 但它的值那时显然未定义。

将其与第一种情况进行比较,其中等效操作是:

char            *line;
get_next_line(fd, &line);
printf("%i-%s\n",i, *line);

在这种情况下,get_next_line 能够有效地更改调用者的 line 变量,如下所示:

*line = malloc(MY_MAX_LINE_LENGTH);

因此,当函数退出时,调用者的 line 变量现在具有有效的内存地址,因此可以安全地取消引用。

关于c - 为什么使用 char** 会导致 char* 工作时出现段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59022713/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com