[英]Why does this dynamic allocation of type char** and char* using malloc segfault?
[英]Why does using a char** cause a segfault where a char* works?
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);
}
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);
}
Part 1 和 Part 2 之间有什么区别吗,它们之间的区别是一个使用**line
,另一个只是*line
。 根据我的理解,两者应该是一样的。
我正在使用它们来测试我自己的读取和返回 1 行函数的实现。
问题:
第 1 部分测试工作正常。 第 2 部分测试结果出现分段错误
get_next_line()
的实现对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
的值是 undefined 因为它从未被初始化。 因此,即使get_next_line
没有取消引用line
, printf
仍然会导致未定义的行为,因为它取消引用了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
变量现在有一个有效的内存地址,因此可以安全地取消引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.