![](/img/trans.png)
[英]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.