【问题标题】:Printing char[] core dump C打印 char[] 核心转储 C
【发布时间】:2012-07-04 10:52:22
【问题描述】:

我正在努力:

printf("Provider: %s\n", Props->providerName);

结构成员(来自外部库)在哪里:

char providerName[256];

导致核心转储,gdb 输出为:

Program terminated with signal 11, Segmentation fault.
[New process 73950    ]
#0  0xfee22290 in strlen () from /lib/libc.so.1

我猜 char[] 可能不会以 null 结尾,但最好的解决方案是什么?

干杯!


编辑:我使用的结构来自外部库,并且似乎不为空(我可以成功打印它的另一个成员 char alias[256];

【问题讨论】:

  • 如何用数据填充providerName
  • 你做了什么让它非空终止?
  • 最好的解决方案是首先将 providerName 终止为空。
  • 您确定Props 是非空且有效的吗?
  • 所以解决一个段错误导致另一个。这是 gdb 和 valgrind 的经典案例。相信我,这样你会更快地解决你的问题,或者至少能够与 SO 分享 real 问题。在 intertubez 上调试非常困难。

标签: c char printf coredump


【解决方案1】:

在将%s 与 printf 一起使用时,尽可能使用最大宽度指示器:

printf("Provider: %.255s\n", Props->providerName);

如果您仍然遇到段错误,并且 Props 不是 NULL,则您的标头和库二进制文件之间可能存在冲突。假设您有新版本的标头定义:

struct Thing {
    int foo[256];
    int bar[256];
    int baz[256];
};

但库二进制文件已过时,使用以下定义:

struct Thing {
    int foo[256];
    int bar[256];
};

如果您现在尝试访问 baz,您将遇到分段错误,即使其他成员工作正常。

(编辑:将“如果您遇到段错误”添加到答案末尾)

【讨论】:

  • 如果实际数据只有10个字符怎么办?虽然它不会出现段错误(这里但在其他一些可能要求它为空终止的字符串函数中,所以我认为这只是隐藏了一个错误),将打印 245 个垃圾字符。
  • 我试过这个并得到一个不同的错误:Program terminated with signal 11, Segmentation fault. [New process 74518 ] #0 0xfee2193c in memchr () from /lib/libc.so.1
  • @Ant 那么Props 可能是NULL 或陈旧的。尝试使用调试器运行您的程序。
  • @AntWilson - 你真的应该使用“valgrind”和“gdb”。您将更快地解决记忆问题。一旦你遇到了我们可以看到的具体问题,你总是可以回到 SO。
  • 发布的错误是使用 gdb 获得的。并且 props 不为空,因为我可以成功打印另一个成员 char alias[256];
【解决方案2】:

更新:printf() 改进为putchar()

已经给出了其他一些很好的答案。但是,如果不想更改 providerName,则调用带有 break 的循环:

int i;
printf("Provider: ");
for (i = 0; i < N; ++i) {
    const char c = Props->providerName[i];
    if (!c) break;
    putchar(c);
}
putchar('\n');

当然,必须早先设置const int N = 256#define N 256 等。如果需要,可以将循环封装在函数调用或宏中。

顺便说一句,上面的循环什么都不做printf() 无论如何都不必做;所以它运行得很快,如果这很重要的话。

【讨论】:

    【解决方案3】:

    Props-&gt;providerName[255] = 0; 在使用之前将确保您的数据以 NULL 结尾。

    【讨论】:

      【解决方案4】:

      如果您想使用 strcpy(Props->providerName, "IBM") 输入“IBM”作为提供者名称。 或使用 gets(str) 在 str 中获取输入,然后使用。 也是使用 gdb 编译程序并使用 p Props 打印值以检查 Props 指向的值的最佳方法

      【讨论】:

        【解决方案5】:

        这似乎与providerName 中包含的数据类型无关。

        Props 很可能确实引用了无效的内存位置,例如 NULL

        您可以使用如下调试修改来测试:

        char * p = Props->providerName;
        printf("Provider: %s\n", p);
        

        我敢打赌它在尝试执行第一行时会崩溃。

        实现这一点的另一种更灵活的方法可能是:

        printf("Provider: %*s%s\n", 
          sizeof (Props->providerName), 
          Props ?Props->providerName :"<no properties available>", 
          Props ?(Props->providerName[sizeof(Props->Props->providerName) - 1] ?" <cut off>" :"") :"");
        

        【讨论】:

        • 如果使用 printf 进行调试,为什么不直接使用printf("Props is at 0x%p\n", Props);
        • 当然 ... - 也可以使用gdb &lt;executable&gt; &lt;core&gt;,然后发出p Props。 ;-)
        • 当然可以,但是你没有建议在你的帖子中使用 gdb,你建议添加一个 printf。
        猜你喜欢
        • 2022-11-03
        • 2019-04-10
        • 1970-01-01
        • 2019-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多