簡體   English   中英

為什么使用 char** 會導致 char* 起作用的段錯誤?

[英]Why does using a char** cause a segfault where a char* works?

第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);
}

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沒有取消引用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變量現在有一個有效的內存地址,因此可以安全地取消引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM