【问题标题】:Segmentation fault and printf warinings分段错误和 printf 警告
【发布时间】:2016-10-23 07:19:09
【问题描述】:

我的程序有一些警告,然后它崩溃了。崩溃似乎与警告有关,但我不明白。这是我的代码:

#include <stdio.h>

struct student {
    char name[100];
    int id;
    char *department;
    struct result {
        float gpa;
        char grade;
    } res;
};

int main(void) {
    struct student W[] = {{"Saud Farooqui",137,"Electronics",{3.05,'A'}},
          {"Talha Farooqui",129,"Civil",{3.5,'A'}}};

    printf("First student data is\n%s\t%d\t%s\t%f\t%c",W[0].name,W[0].id,
         W[0].department,W[1].res.gpa,W[0].res.grade);

    printf("\nSecond student data is\n%s\t%d\t%s\t%f\t%c",W[1].name,W[1].id,
         W[1].res.gpa,W[1].res.grade);
}

编译器在第二个printf 中打印出这些关于格式说明符的警告:

foo.c:24:10: warning: format '%s' expects argument of type 'char *', but argument 4 has type 'double' [-Wformat=]
          W[1].res.gpa,W[1].res.grade);
          ^
foo.c:24:10: warning: format '%f' expects argument of type 'double', but argument 5 has type 'int' [-Wformat=]
foo.c:24:10: warning: format '%c' expects a matching 'int' argument [-Wformat=]

当我尝试启动程序时,第一个printf 打印了一行,但第二个失败了:

 Segmentation fault (core dumped)

它有什么问题?如何修复警告和崩溃?

【问题讨论】:

  • 警告信息中有哪些不清楚的地方?而且您不认为段错误与您忽略警告有关吗?你知道警告很有用。你把它弄错了。首先修复警告,也许你的代码会运行,就像那样。
  • 我尝试重新整理一下信息,现在我认为这个问题更具可读性和相当不错的问题。

标签: c linux struct segmentation-fault format-specifiers


【解决方案1】:

department 缺少一个参数。很明显,当你编译 它打开了警告(-Wall):

a.c:21:7: warning: format ‘%s’ expects argument of type ‘char *’, but argument 4 has type ‘double’ [-Wformat=]
       W[1].name, W[1].id,  W[1].res.gpa, W[1].res.grade);
       ^
a.c:21:7: warning: format ‘%f’ expects argument of type ‘double’, but argument 5 has type ‘int’ [-Wformat=]
a.c:21:7: warning: format ‘%c’ expects a matching ‘int’ argument [-Wformat=]

另外,您的第一个printf 打印出W[1].res,它可能应该是W[0].res

固定版本:

struct student W[] = {{"Saud Farooqui",137,"Electronics",{3.05,'A'}},
  {"Talha Farooqui",129,"Civil",{3.5,'A'}}};

printf("First student data is\n%s\t%d\t%s\t%f\t%c",
    W[0].name, W[0].id, W[0].department, W[0].res.gpa, W[0].res.grade);

printf("\nSecond student data is\n%s\t%d\t%s\t%f\t%c",
    W[1].name, W[1].id, W[1].department, W[1].res.gpa, W[1].res.grade);

所以分段错误是由于试图将W[1].res.gpa解释为指向字符串的指针(对应于%s格式说明符),即const char *

【讨论】:

  • 不应该是W[1].department吗?
  • 虽然它不会导致分段违规,但第一个printf中的W[1].res不应该是W[0].res吗?而不是整个事情作为一个循环会更好吗?
  • 你确定 OP 不是指W[1].res
  • @msw,是的,因为第一个学生在第一个索引下,即0
  • 投票关闭,我忘了这样做。我同意大多数问题都包含一些琐碎的内容,但是这个问题可以通过阅读警告来单独解决,但有时这很复杂,所以值得回答。这里的修复很简单,几乎是一个错字。远离周日问题,多次被否决,其中包含“学生”,而且微不足道。无论如何,你得到了 2 票,所以它很平衡,你可以侥幸逃脱。
猜你喜欢
  • 2020-08-29
  • 1970-01-01
  • 1970-01-01
  • 2012-03-17
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多