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

标签 c pointers double-pointer

第 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/

相关文章:

c++ - 从 CArray 指针访问值

c - 修改指向整数数组的双指针

c - 无法取消引用c中的双指针

C通过引用传递字符串到函数

c - 在目录中循环并在 c 中获取其文件

c - 带有 char 数组的 sscanf 始终评估为 true

c - c中按位运算的解释

c++ - QT 程序在 connect() 后崩溃

PHP指针和变量冲突

c - C 函数中的参数传递