c - "memset"设置结构导致 printf 打印结构成员的长度超过其限制

标签 c struct gdb memset

我在一个非常大的 C 程序中发现了这个问题。

结构声明是:

struct kc910InputParms {
    char inStream[71];
}

在程序中,当对该结构变量进行memset操作时,printf语句打印的长度超过了它的限制(即71个字符是限制)。请看下面在 gdb 中调试时获得的输出。

(gdb) s
cpyInParmsToCbl (in=0xffffb9f6, out=0x80ef320) at kc190Common.c:456
456       memset((void*)out, ' ', sizeof(kc910InputParms));
(gdb) printf "<%s>\n", out.inStream
<>
(gdb) n
458       strncpy(out->inStream+16, in->system_id,strlen(in->system_id));
(gdb) printf "<%s>\n", out.inStream
<                                                                       Pending>

请注意上面:有 7 个额外的字符附加为“Pending”,打印 out.inStream 最多 78 个字符。这给程序的后续阶段带来了缺陷。

谁能帮我理解这种行为以及使用 memset 的正确方法(如果我做错了)?

如果发生这种情况是因为变量 out.inStream 没有被空字符 '\0' 终止,那么我的问题是:为什么它没有在 memset ?

之前以同样的方式打印

最佳答案

这是由于缺少终止nul。之前之所以能正常工作是因为编译器将内存区域设置为nul,或者只是随机运气。

您还告诉 strncpy 空间只能容纳与字符串中的字符一样多的字节,因此它不会添加终止符。这是错误的做法。您应该告诉 strncpy 目标 中有多少字节可用,而不是 中有多少字符。在这种情况下 54 (70-16)。对于源长度超过 54 个字符的情况,您应该明确地将最后一个字节设置为 nul。

printf 和其他 C 字符串函数对数组大小或内存分配一无所知,它们以 nul 结尾。因此,如果您没有它,它们将继续,直到找到一个,可能会用完分配的内存空间并导致未定义的行为。这就是为什么您在输出中得到超过 71 个字符的原因。

关于c - "memset"设置结构导致 printf 打印结构成员的长度超过其限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34463239/

相关文章:

c - 如何将 typedef 结构传递给函数?

c - 如何在GDB模式下传递输入数据进行编程 C. 已传递参数并运行程序

c - 在gdb中打印结构元素

c - 通过 curl 使用摘要身份验证

c++ - 可变数量的参数

c++ - 将对象初始化为全零

c++函数指针和void指针交互导致奇怪的事情

c++ - GDB/DDD 当前上下文中没有符号 <var>

c - C 中从 16 位到 32 位的符号扩展

c - 你如何创建一个调用c lua api的lua插件?