【问题标题】:Malloc / Free with enum gives segmentation fault - simple code带枚举的 Malloc / Free 会导致分段错误 - 简单的代码
【发布时间】:2014-08-13 21:32:58
【问题描述】:

我试图为单个枚举变量分配一些内存,但我的代码给了我分段错误。它按原样打印出 2 和 3,但最后也显示 seg fault,为什么?

我正在使用 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("%d\n", d1);

    enum direction *d2;
    d2 = malloc(sizeof(enum direction));
    d2 = right;
    printf("%d\n", d2);
    free(d2);

    return 0;
}

【问题讨论】:

  • 尝试:*d2 = 对; printf("%d\n", *d2);
  • 你编译时是否启用了任何警告?因为编译器应该闪烁警告灯。

标签: c enums segmentation-fault malloc free


【解决方案1】:

d2 是指针,而不是枚举。您不能为其分配枚举值。应该是

*d2 = right;

这将取消对指针的引用,并且您将right 放入d2 指向的内存中。你这样做的方式会覆盖指针本身。

您还应该在使用malloc 之前检查它的返回值,以确保它是一个有效的指针。

d2 = malloc(sizeof(enum direction));

if (d2 != NULL)
{
    *d2 = right;
    ...
    free(d2);
}
else
{
    // handle error
}

【讨论】:

  • @BrianBrown Lol,每个人都会遇到。 :)
  • 显然他可以将枚举分配给d2,因为程序已编译并运行。
  • @DavidHeffernan 我的意思是说将枚举分配给指针是不合法的。根据编译器设置,问题可能会被隐藏。我对 gcc 不是很熟悉。
  • @Deduplicator 合法的只是将任何二进制值放在任何内存位置是合法的。这并不意味着它会起作用。将right 放在指针中从广义上讲是合法的。
  • 我认为赋值是非法的,UB,编译器至少有义务警告:stackoverflow.com/questions/10640943/…
【解决方案2】:

这里

printf("%d\n", d2);

您将指针传递给%d 格式说明符,这会导致未定义的行为。

这里

d2 = right;

当您调用malloc 时,您会覆盖保存分配的动态内存地址的变量。因此

free(d2);

试图释放没有用malloc 分配的东西。这会导致未定义的行为。

大概是你的意思

*d2 = right;
printf("%d\n", *d2);

我建议您打开所有警告并注意它们。如果您这样做,我相信您的编译器可以在您运行程序之前识别问题。

【讨论】:

  • 你为什么不把最后一段 bold?这就是提问者的问题,剩下的只是表象。
【解决方案3】:

这个

d2 = right;

是一个格式错误的表达式语句。 d2 是一个指针。 right 是一个整数。将整数值分配给指针是非法的(除非整数是零常量)。这是 C 语言中的“错误”。它不会在迂腐的 C 编译器中编译。任何兼容的编译器都需要为此分配发出诊断消息。 GCC 编译器也这样做。显然,您只是忽略了该诊断消息。这意味着您的程序的行为不是由 C 语言定义的。它不是 C 程序。

您可能忽略的另一条 GCC 诊断消息是此语句的消息

printf("%d\n", d2);

它应该告诉你printf-ing 通过%d 格式说明符的指针是非法的。

不要忽略编译器发出的诊断消息。在许多情况下,这将帮助您自己回答“为什么我的程序会出现段错误”之类的问题。

附:作为一个奇怪的旁注:d2 = up; 实际上是一个完全有效的分配。程序不会崩溃,它只会泄漏内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    相关资源
    最近更新 更多