0

我正在尝试做:

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];

4

5 回答 5

2

%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,即使其他成员工作正常,您也会遇到分段错误。

(编辑:从“如果你得到一个段错误”添加文本到答案的结尾)

于 2012-07-04T10:57:55.110 回答
1

更新: 改进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()需要做任何事情;所以它运行得很快,如果这很重要的话。

于 2012-07-04T11:14:24.963 回答
0

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

于 2012-07-04T11:02:34.890 回答
0

这似乎与中包含的数据类型无关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>" :"") :"");
于 2012-07-04T11:04:07.353 回答
0

Props->providerName[255] = 0;在使用它之前,它将确保您的数据以 NULL 终止。

于 2012-07-04T10:56:11.960 回答