我试图为单个enum变量分配一些内存,但我的代码给了我分段错误。它打印出2和3,但在最后显示segfault,为什么?
我使用的是gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
#include <stdio.h>
#include <stdlib.h>
enum direction
{
up, down, left, right
};
int main(int argc, char **argv)
{
enum direction d1;
d1 = left;
printf("%dn", d1);
enum direction *d2;
d2 = malloc(sizeof(enum direction));
d2 = right;
printf("%dn", d2);
free(d2);
return 0;
}
d2
是指针,不是enum。不能为其分配枚举值。应该是
*d2 = right;
对指针进行解引用,将right
放入d2
所指向的内存中。这样做会覆盖指针本身。
在使用malloc
之前,您还应该检查它的返回值,以确保它是一个有效的指针。
d2 = malloc(sizeof(enum direction));
if (d2 != NULL)
{
*d2 = right;
...
free(d2);
}
else
{
// handle error
}
这里
printf("%dn", d2);
传递一个指向%d
格式说明符的指针,这会导致未定义的行为。
和
d2 = right;
将覆盖保存调用malloc
时分配的动态内存地址的变量。因此
free(d2);
尝试释放没有分配给malloc
的东西。这会导致未定义的行为。
你大概是指
*d2 = right;
printf("%dn", *d2);
我建议你打开所有的警告并注意它们。如果您这样做,我相信您的编译器甚至可以在运行程序之前识别出问题。
This
d2 = right;
是一个格式错误的表达式语句。d2
是指针。right
为整数。给指针赋整数值是非法的(除非该整数值为零常量)。这是C语言中的"错误"。它不会在迂腐的C编译器中编译。任何兼容的编译器都需要为此赋值发出诊断消息。GCC编译器也这样做。显然,你只是忽略了诊断信息。这意味着程序的行为不是由C语言定义的。它不是一个C程序。
您可能忽略的另一个GCC诊断消息是以下语句
printf("%dn", d2);
它应该告诉你printf
-ing指针通过%d
格式说明符是非法的。
不要忽略编译器发出的诊断消息。在许多情况下,这将帮助您自己回答诸如"为什么我的程序出现分段错误"之类的问题。
注:作为一个奇怪的旁注:d2 = up;
实际上是一个完全有效的赋值。程序不会崩溃,它只会泄漏内存。