"memset"设置结构会导致 printf 打印结构成员的长度超过其限制
"memset"ting a struct causes printf to print struct member longer than its limit
我在一个非常大的 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
没有被空字符 '[=18=]'
终止,那么我的问题是:为什么它在 [=13] 之前没有以相同的方式打印=] ?
这是由于缺少终止nul。之前之所以能正常工作是因为编译器将内存区域设置为nul,或者只是随机运气。
您还告诉 strncpy
space 的字节数与字符串中的字符数一样多,因此它没有添加终止符。这是错误的做法。您应该告诉 strncpy
destination 中有多少字节可用,而不是 source 中有多少字符。在这种情况下 54 (70-16)。对于源长度超过 54 个字符的情况,您应该明确地将最后一个字节设置为 nul。
printf
和其他 C 字符串函数对数组大小或内存分配一无所知,它们以 nul 结尾。因此,如果您没有它,它们将继续,直到找到一个,可能 运行 超出分配的内存 space 并导致未定义的行为。这就是为什么您在输出中得到超过 71 个字符的原因。
我在一个非常大的 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
没有被空字符 '[=18=]'
终止,那么我的问题是:为什么它在 [=13] 之前没有以相同的方式打印=] ?
这是由于缺少终止nul。之前之所以能正常工作是因为编译器将内存区域设置为nul,或者只是随机运气。
您还告诉 strncpy
space 的字节数与字符串中的字符数一样多,因此它没有添加终止符。这是错误的做法。您应该告诉 strncpy
destination 中有多少字节可用,而不是 source 中有多少字符。在这种情况下 54 (70-16)。对于源长度超过 54 个字符的情况,您应该明确地将最后一个字节设置为 nul。
printf
和其他 C 字符串函数对数组大小或内存分配一无所知,它们以 nul 结尾。因此,如果您没有它,它们将继续,直到找到一个,可能 运行 超出分配的内存 space 并导致未定义的行为。这就是为什么您在输出中得到超过 71 个字符的原因。