首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么这样使用malloc?

为什么这样使用malloc?
EN

Stack Overflow用户
提问于 2012-02-06 08:29:46
回答 4查看 292关注 0票数 1

我正在编写我向一个研究团队请求的代码。我正在尝试理解代码,然而,他们以一种奇怪的方式使用malloc。这里;

在头文件中;

代码语言:javascript
运行
复制
 #define ERROR_OUTPUT stderr
 #define FAILIF(b) {   \
   if (b) {  \
       fprintf(ERROR_OUTPUT, "FAILIF triggered on line %d, file %s. Memory allocated: %lld\n",  \
       __LINE__, __FILE__, totalAllocatedMemory); exit(1); \
   } \
  }
 #define MALLOC(amount) \ 
   ( (amount > 0) ? totalAllocatedMemory += amount, malloc(amount) : NULL)

在cpp文件中;

代码语言:javascript
运行
复制
 double *memRatiosForNNStructs = NULL;
 double *listOfRadii = NULL;
 nRadii = 1;
 FAILIF(NULL == (memRatiosForNNStructs = (double*)MALLOC(nRadii * sizeof(double))));

根据我的理解,他们定义的MALLOC的含义如下;

代码语言:javascript
运行
复制
if(amount>0) // which is true; at least in this case
{
   totalAllocatedMemory = totalAllocatedMemory + amount; // sounds reasonable
   malloc(amount)  // What?? This will leak memory...
}
else
{
   NULL; // Do nothing? I guess that's fine
}

我是不是漏掉了什么?或者他们只是犯了一个(幼稚的)错误?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-02-06 08:33:11

您拥有的第三个代码片段不是等价的。注意the comma operator的用法

代码语言:javascript
运行
复制
#define MALLOC(amount) \
    ( (amount > 0) ? totalAllocatedMemory += amount, malloc(amount) : NULL)  
                                                   ^
                                                  N.B.!

逗号运算符接受两个参数,计算并丢弃第一个表达式,然后计算并返回第二个表达式。

ternary conditional operator是这样使用的

代码语言:javascript
运行
复制
a = ((b)?(c:d))

等同于这个

代码语言:javascript
运行
复制
if(b) {
    a = c;
}
else {
    a = d;
}

逗号运算符使用这种方式

代码语言:javascript
运行
复制
e = f, g;

等同于这个

代码语言:javascript
运行
复制
f;
e = g;

所以如果你有

代码语言:javascript
运行
复制
a = ((b)?(f,g:d))

那么这就相当于

代码语言:javascript
运行
复制
if(b) {
    f;
    a = g;
}
else {
    a = d;
}

在您的原始帖子中提供的代码中,MALLOC宏的用法如下:

代码语言:javascript
运行
复制
memRatiosForNNStructs = (double*)MALLOC(nRadii * sizeof(double));

这相当于:

代码语言:javascript
运行
复制
   // First operand of ternary conditional
if(nRadii * sizeof(double) > 0)
{
    // Second  operand of ternary conditional

    // First expression of the comma operator
    totalAllocatedMemory += nRadii * sizeof(double));
    // Second expression of the comma operator
    memRatiosForNNStructs = (double*)malloc(nRadii * sizeof(double));
}
else
{
    // Third operand of ternary conditional
    memRatiosForNNStructs = (double*)NULL;
}

但老实说,这可以作为C语言中的一个函数来实现,而不会损失通用性:

代码语言:javascript
运行
复制
void* my_malloc(unsigned int amount)
{
    if(amount > 0) {
        // I assume this is a global variable
        totalAllocatedMemory = totalAllocatedMemory + amount;
        return  malloc(amount);
    }
    else {
        return NULL;
    } 
}

memRatiosForNNStructs = (double*)my_malloc(nRadii * sizeof(double));

因此,我甚至不确定将其作为难以阅读的宏来实现的意义。

票数 8
EN

Stack Overflow用户

发布于 2012-02-06 08:35:13

您要处理的是逗号运算符,它按顺序计算每个操作数并返回最后一个操作数的返回值。因此,a + b, malloc(n)首先计算a + b,然后计算malloc(n),然后返回后者的结果。所以整个三元条件表达式的返回类型是void *

与三元表达式最接近的是一个函数:

代码语言:javascript
运行
复制
void * MALLOC(unsigned int n) {
   if (n > 0) {
      totalAllocatedMemory += n;
      return malloc(n);
   } else {
      return NULL;
   }
}
票数 3
EN

Stack Overflow用户

发布于 2012-02-06 08:35:22

他们使用了令人困惑的三元运算符和逗号运算符的组合。

请记住:

  • 三元运算符计算其第一个操作数,如果第一个操作数为真,则返回第二个操作数;
  • 逗号运算符计算两个操作数并返回第二个操作数。

因此,如果为amount>0,则表达式将返回totalAllocatedMemory += amount, malloc(amount);由于逗号运算符会执行这两个表达式,但只返回第二个表达式,因此表达式的最终返回值是malloc中的值。

尽管如此,如果这个丑陋的宏是一个内联函数,那么它会更清晰(并且没有性能损失)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9154412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档