我在 C 程序中使用了一个特定的数据结构,我用它来将类型信息附加到值。一个简单的示例如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct teststruct
{
char type;
union {
char s;
int i;
float f;
} value;
};
int main()
{
struct teststruct *t = malloc(sizeof(struct teststruct)+10);
t->type = 'i';
t->value.i = 42;
free(t);
t = malloc(sizeof(struct teststruct)+10);
t->type = 's';
strcpy(&t->value.s, "test");
free(t);
printf("Finished without errors.\n");
}
如您所见,我的意图是使用type
字段来识别值的类型,并使用value
字段来包含可能值的联合。当数据是字符串时,想法是分配更多的内存sizeof(struct teststruct)
,然后使用&t->value.s
.
虽然这可行,但对于优化器来说显然是有问题的。使用gcc
4.7.2 版,我在非优化条件下得到以下结果:
$ gcc -O0 -o test test.c
$ ./test
Finished without errors.
没问题。但是,在优化器下,它给了我一个警告:
$ gcc -O2 -o test test.c
In file included from /usr/include/string.h:642:0,
from test.c:4:
In function ‘strcpy’,
inlined from ‘main’ at test.c:25:15:
/usr/include/i386-linux-gnu/bits/string3.h:105:3: warning: call to __builtin___memcpy_chk will always overflow destination buffer [enabled by default]
确实,
$ ./test
*** buffer overflow detected ***: ./test terminated
但是,如果我替换strcpy
为memcpy
,这可以正常工作,如果我替换strcpy
为for
-loop 也可以很好地工作。但是,strncpy
崩溃就像strcpy
. 我绝对不会在malloc
'ed 内存之外被覆盖,所以我不知道为什么会崩溃。
我意识到复制到数据结构的奇怪偏移量并不常见,所以问题是,我是否违反了 的某些语义契约strcpy
,或者这是编译器中的错误?
谢谢。