【问题标题】:Segmentation Fault when using getline() C使用 getline() C 时出现分段错误
【发布时间】:2017-03-11 13:35:14
【问题描述】:

我查看的每个其他线程都存在未将 line 初始化为 NULL 和 len 为 0 的问题。这是我的代码的一部分:

    char* line = NULL;
    char* line2 = NULL;
    size_t len = 0;
    size_t len2 = 0;
    char *function = NULL;
    size_t read, read2;       //read2 gia to config
    while ((read = getline(&line, &len, op)) != -1)
    {
            line[read - 2] = 0;
            char* pch;
            pch = strtok(line, " ");
            strcpy(function, pch);

提前致谢。

【问题讨论】:

  • 如果read < 2怎么办?
  • 什么意思?你的意思是当你在它们的定义中编码时变量没有被初始化?你的意思是lineNULL 并且len0 调用getline 之后?你能详细说明一下吗?如果可能的话,请创建一个Minimal, Complete, and Verifiable Example 向我们展示。
  • 你为什么这么肯定,getline() 是段错误的原因?你肯定没有使用调试器,否则你可能已经发现了你的错误,那么你怎么知道它不是之后的strcpy(),它试图复制一些东西到存储在*function 中的NULL 指针?你的意思是function = strdup(pch);吗?
  • 由于您没有显示使用line2len2read2 的代码,也没有显示循环的其余部分,我们无法判断未显示的代码是否存在问题. MCVE (minimal reproducible example) 不会包含这些变量。 (就个人而言,如果我有两组变量,它们会是line1line2,而不是lineline2,但是很多人都按照你的方式做——当我看到它时,我很生气。 )。但是,您还没有为 function 分配空间来指向,所以 strcpy(function, pch) 失败 - 可能是分段错误。
  • 这是错误的:strcpy(function, pch); 因为function 没有指向您的程序拥有的内存。 (它指向NULL,实际上是地址0;

标签: c getline


【解决方案1】:

您的代码有多个问题,

  1. 如果read < 2 则您的索引小于0
  2. 如果pchNULL,那么您取消引用NULL 指针

    关于strtok()的说明,

    • 找不到分隔符时返回NULL
    • 处理多个字符串或在多线程程序中使用它真的很糟糕,因为它不可重入。
    • 总有更好的选择,涉及strchr()strstr()strpbrk(),所有这些都没有strtok() 的限制。

    注意,我并不是说您不应该使用strtok(),在某些合法情况下它是最佳选择,我只是警告您它的一些限制并澄清它的预期行为,以便您正确使用它,假设它仅仅因为您“知道”输入而返回了一些东西,这只是一种糟糕的编程习惯。总是检查错误,最好知道程序失败的原因,而不是完全困惑。

    事实上,说或认为“你知道输入”是错误的,因为

    1. 编写处理单个输入的代码有什么意义?

    2. 不是你想的那样,有些字符对你来说可能很清楚,但是编辑器可以渲染一个 '\t' 制表符,就像他们处理 ' ' 空白一样。

你不应该把它归咎于getline(),因为它可以正常工作,所以这几乎不是错。

您的程序调用了未定义的行为,因此无法确定问题究竟发生在哪里,因为它可能发生在某个地方并且程序会继续运行,直到有人做了一些触发分段错误的事情。

【讨论】:

  • 我毫不怀疑程序的其余部分存在多个问题,感谢您的提示。但它在移动到其余行之前确实达到了分段错误,所以我对为什么感到困惑。
  • 未定义的行为,意味着您无法知道 SIGSEGV 将在哪里发生。
  • @meerto 只需使用调试器并逐行执行代码,您就会突然说“哦!这就是问题所在,ohhhh 我好.... ", ;)
  • 哈哈!我做了gdb,但我在使用它方面还很新。它抱怨:“程序收到信号 SIGSEGV,分段错误。_IO_getdelim (lineptr=0x7fffffffdcc0, n=0x7fffffffdcc8, delimiter=10, fp=0x0) at iogetdelim.c:52 52 iogetdelim.c: 没有这样的文件或目录。”跨度>
猜你喜欢
  • 2019-06-13
  • 2017-03-26
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
  • 2011-02-27
  • 2020-05-29
  • 1970-01-01
  • 2020-08-02
相关资源
最近更新 更多