【问题标题】:Segmentation fault for c programc程序的分段错误
【发布时间】:2015-02-17 19:03:59
【问题描述】:

这里的代码出现分段错误。

gdb:

Program received signal SIGSEGV, Segmentation fault.
_IO_fgets (buf=0x601080 <rc> "", n=100, fp=0x0) at iofgets.c:50
50  iofgets.c: No such file or directory.

代码:

#include <unistd.h>
#include <stdio.h>

char rc[100];
FILE *fp;
int status;

void main() {    
    fp = popen("sudo lshw |", "grep UUID");
    if (fp == NULL)
        printf("NULL pointer");
    while (fgets(rc, 100, fp) != '\0')
        printf("%s", rc);
    status = pclose(fp);
    if (status == -1) {
        printf("pclose error");
        /* Error reported by pclose() */
    } else{
        printf("Unknown error");
    }
    //return 0;
}

我猜是空指针?我尝试了给出的解决方案,但没有奏效。我猜是个愚蠢的错误

对不起,shell 命令将 b sudo dmidecode | grep UUID

【问题讨论】:

  • 请编辑问题以在崩溃发生时显示完整的函数调用堆栈。问题不在库代码中,而在您的代码中。
  • 你的变量都是全局变量有什么好的理由吗?我看到你声明了void main() 而不是int main() 这是正确的方式,并评论了return 0;
  • 我猜您可能希望打印该错误消息而不是继续从无效文件指针读取,而不是另外
  • 另请注意,fgets 返回的缓冲区(或 NULL)不是单个字符。
  • @JohnBollinger NULL'\0' 在某些编译器上恰好相同并不意味着它们总是如此。 NULL 是“空”指针'\0'字符,它们本质上是不同的并且比较这两者(如果编译器允许并且不对你尖叫)将导致未定义的行为。

标签: c segmentation-fault


【解决方案1】:

这是错误的

fp = popen("sudo lshw |", "grep UUID");

也许你的意思是,阅读popen()

fp = popen("sudo lshw | grep UUID", "r");

调用失败,但即使您检查了fp == NULL,您仍然继续导致未定义的行为,并导致分段错误,fp == NULL 检查需要中止程序,像这样

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

int main() {    
    char  rc[100];
    FILE *fp;
    int   status;

    fp = popen("sudo lshw | grep UUID", "r");
    if (fp == NULL)
    {
        printf("error:%d: %s", errno, strerror(errno));
        return -1;
    }
    while (fgets(rc, 100, fp) != NULL)
        printf("%s", rc);
    status = pclose(fp);
    if (status == -1) {
        printf("error:%d: %s", errno, strerror(errno));
    } else { /* this means no error happened */
        printf("success: pipe, closed.");
    }
    return 0;
}

注意main() 应该返回一个int,正如Joachim Pileborg 所评论的,fgets(...) == '\0' 是错误的,fgets() 在错误时返回NULLNULL == '\0' 不一定是真的。

此外,pclose() 在错误时返回 -1,如果它不返回 -1,那么一切都按预期进行。

【讨论】:

  • 分段错误消失了,但我没有得到系统调用结果,而是给出了 Unknown error which is last printf
  • 你不应该为此编写c程序,特别不要使用sudo,只需编写一个shell脚本。要检查错误发生的原因,您可以#include &lt;errno.h&gt; 并在popen() 之后检查errno
  • 我在尝试系统调用时需要写一个c,因此需要它
  • 令人惊讶的是它在 lshw 中没有失败,但也没有打印缓冲区的值。
  • @anupam_on 我更新了代码,但你也得到了pclose() 错误,如果它没有返回-1 则没有发生错误,请注意在你的代码中,不管是什么pclose()返回你总是认为这是一个错误。
猜你喜欢
  • 2021-01-08
  • 1970-01-01
  • 2012-10-12
  • 2018-11-18
  • 2011-05-23
  • 2015-06-14
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多