【问题标题】:Assignment in condition of if goes wrongif 出错时的赋值
【发布时间】:2016-10-09 23:09:47
【问题描述】:

我正在使用这行代码为结构动态分配内存:

if (DrinkMachine = (Drink_Machine*)malloc(sizeof(DrinkMachine) * size) == NULL)
    return(NULL);

我也试过了:

if (DrinkMachine = (Drink_Machine*)malloc(sizeof(DrinkMachine[size])) == NULL)
    return(NULL);

现在,由于我的代码(某处)出现错误,它无法动态分配内存,并且指针确实为 NULL。但是,它不会返回 NULL,或者尝试输入 if 语句,即使它应该为真。什么给了?

编辑:附加信息。当我单步调试调试器时,我的结构中的每个项目都会在手表中显示“无法读取内存”。不知道这是否对任何人有帮助,但我想我会把它添加到问题中。

Edit2:所以这个答案得到了回答,我只是想让它在编辑中可见。

if ((DrinkMachine = (Drink_Machine*)malloc(sizeof(Drink_Machine) * size)) == NULL)
    return NULL;

这是键入此内容的正确方法。请注意,我还编辑了代码以在 sizeof() 中正确显示 Drink_Machine。不包括那是一个错字。其他人则表示,显然,单独声明代码然后在下一条语句中测试指针更聪明。 (并纠正了一个错字)

感谢所有花时间回答这个问题的人!

【问题讨论】:

  • @PaulRooney,一个是(选择不当)变量名,另一个是类型。没有错。
  • @StoryTeller 如果他使用 Visual Studio,他可以投射
  • 如果你写了DrinkMachine = malloc( ... ); if (NULL == DrinkMachine) {...},你就不会遇到这个问题。保存那一行代码值得吗?
  • @self,拥有 Visual Studio 是做任何事情的一个糟糕的理由,尤其是用被认为越来越糟糕的风格写作。

标签: c pointers malloc


【解决方案1】:

您需要将赋值用括号括起来以强制优先。

if((DrinkMachine = (Drink_Machine *)malloc(sizeof(Drink_Machine) * size)) == NULL) {
    /* DrinkMachine is NULL */
}

【讨论】:

  • 这是不正确的,分配的内存将是指针的大小,而不是“DrinkMachine”对象的大小。
  • Drink_Machine 是对象,我假设它是 typedef
【解决方案2】:

==higher precedence 具有 =

因此首先计算==(导致01)并将其分配给您的指针。

【讨论】:

  • 有些人继续想知道为什么我认为条件子句中的赋值是一个BAD的想法...
  • 是的,我花了很长时间才真正写出来,我不得不用自动括号打开一个编辑器,因为它很难解析
  • @self 是的。 25 年来我一直在用 C 编码(哎哟!),我认为处理运算符优先级是浪费精力 - 我宁愿专注于 what 发生的事情,而不是浪费时间顺序。 IMO 的“条件子句赋值”风格来自教科书,其中保存代码行很重要——几万本教科书上的几页将有助于支付某人的游泳池费用。但是代码行数在现实世界中是无关紧要的。
  • ^-- 这里就是这种情况。如果可能的话,我总是被告知要压缩代码。这不是常态吗?
  • @JonathanMartin 我们更喜欢可读可维护的代码。除非您参加混淆 C 竞赛ioccc.org,否则没有理由在同一条线路上拼凑在一起。
【解决方案3】:

关于这一行:

if (DrinkMachine = (Drink_Machine*)malloc(sizeof(DrinkMachine) * size) == NULL)
return(NULL);

1) 不要从任何堆内存分配函数(malloc、calloc、realloc)中转换返回值

2) 变量DrinkMachine 必须是一个指针。所以表达式:sizeof(DrinkMachine) 将返回指针的大小而不是 Drink_Machine 的大小。

3) 语法也不正确。应该是:

if ( (DrinkMachine = malloc(sizeof(*DrinkMachine) * size) ) == NULL)
return(NULL);

4) 当系统函数返回错误指示时,该错误的识别应遵循:(在这种情况下)

{
    perror( "malloc for DrinkMachine failed" );
    // the code has failed, so cleanup and exit
    cleanup();
    exit( EXIT_FAILURE );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-18
    • 2011-10-30
    • 2019-11-22
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    • 2014-11-25
    相关资源
    最近更新 更多