[英]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);
}
Is there any difference between Part 1 and Part 2, the difference between them is one use **line
and another just *line
. Part 1 和 Part 2 之间有什么区别吗,它们之间的区别是一个使用
**line
,另一个只是*line
。 From my understanding, both should be the same.根据我的理解,两者应该是一样的。
I am using them to test my own implementation of a function that reads and return 1 line.我正在使用它们来测试我自己的读取和返回 1 行函数的实现。
The problem:问题:
Part 1 test works fine.第 1 部分测试工作正常。 Part 2 testing results in segmentation fault
第 2 部分测试结果出现分段错误
The implementation of get_next_line()
remain same for both. get_next_line()
的实现对get_next_line()
保持相同。
In the first case using &line
passes a valid address to get_next_line
.在第一种情况下,使用
&line
将有效地址传递给get_next_line
。 But in the second case, using line
passes an uninitialised variable to the function.但在第二种情况下,使用
line
将一个未初始化的变量传递给函数。 You didn't show get_next_line
but I assume it does something like *line = blah
which of course will seg fault if the passed in line
value is not a valid address (technically it's undefined behaviour to dereference an uninitialised pointer so it's likely to seg fault but may also exhibit any other behaviour).您没有显示
get_next_line
但我认为它执行了类似*line = blah
,如果传入的line
值不是有效地址,当然会出现段错误(从技术上讲,取消引用未初始化的指针是未定义的行为,因此很可能会出现段错误但也可能表现出任何其他行为)。
Another way to look at it:另一种看待它的方式:
char **line;
get_next_line(fd, line);
printf("%i-%s\n",i, *line);
That is essentially what the second case does.这基本上就是第二种情况的作用。 We know in C that function arguments are passed by value.
我们知道在 C 中函数参数是按值传递的。 So there is no way that
get_next_line
can change the value of the caller's line
variable.所以
get_next_line
无法改变调用者line
变量的值。 So when the function returns the value of line
is undefined since it was never initialised.所以当函数返回
line
的值是 undefined 因为它从未被初始化。 So even if get_next_line
does not dereference line
the printf
will still cause undefined behaviour as it dereferences line
but it's value is clearly undefined at that point.因此,即使
get_next_line
没有取消引用line
, printf
仍然会导致未定义的行为,因为它取消引用了line
但此时它的值显然是未定义的。
Compare that to the first case where the equivalent opertations are:将其与等效操作为的第一种情况进行比较:
char *line;
get_next_line(fd, &line);
printf("%i-%s\n",i, *line);
In this case, get_next_line
is able to validly change the caller's line
variable with something like:在这种情况下,
get_next_line
能够使用以下内容有效地更改调用者的line
变量:
*line = malloc(MY_MAX_LINE_LENGTH);
So when the function exits the caller's line
variable now has a valid memory address and hence can be safely dereferenced.所以当函数退出时,调用者的
line
变量现在有一个有效的内存地址,因此可以安全地取消引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.