簡體   English   中英

為什么使用malloc這樣?

[英]Why was malloc used this way?

我正在按照研究小組的要求編寫代碼。 我試圖理解代碼,但是,他們以奇怪的方式使用了malloc。 這里;

在頭文件中;

 #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文件中;

 double *memRatiosForNNStructs = NULL;
 double *listOfRadii = NULL;
 nRadii = 1;
 FAILIF(NULL == (memRatiosForNNStructs = (double*)MALLOC(nRadii * sizeof(double))));

根據我的理解,他們定義的MALLOC含義如下;

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
}

我在這里缺少什么嗎? 還是他們只是犯了一個(幼稚的)錯誤?

您擁有的第三個代碼段不相等。 注意使用逗號運算符

#define MALLOC(amount) \
    ( (amount > 0) ? totalAllocatedMemory += amount, malloc(amount) : NULL)  
                                                   ^
                                                  N.B.!

逗號運算符有兩個參數,求值並放棄第一個表達式,然后求值並返回第二個表達式。

三元條件運算符使用這種方式

a = ((b)?(c:d))

相當於這個

if(b) {
    a = c;
}
else {
    a = d;
}

逗號運算符使用這種方式

e = f, g;

相當於這個

f;
e = g;

所以如果你有

a = ((b)?(f,g:d))

那等於

if(b) {
    f;
    a = g;
}
else {
    a = d;
}

在原始帖子提供的代碼中,將使用MALLOC宏,如下所示:

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

這等效於:

   // 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中的函數來實現,而不會失去一般性:

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));

因此,我不確定將其實現為難以讀取的宏有什么意義。

您正在處理逗號運算符 ,該運算符按順序評估每個操作數,並返回最后一個操作數的返回值。 因此, a + b, malloc(n)首先計算a + b ,然后是malloc(n) ,然后返回后者的結果。 因此,整個三元條件表達式的返回類型為void *

三元表達式的最佳近似是一個函數:

void * MALLOC(unsigned int n) {
   if (n > 0) {
      totalAllocatedMemory += n;
      return malloc(n);
   } else {
      return NULL;
   }
}

他們正在使用三元運算符和逗號運算符的混淆組合。

請記住:

  • 三元運算符計算其第一個操作數,如果第一個為真,則返回第二個,否則為第三個;
  • 逗號運算符計算兩個操作數並返回第二個。

因此,如果amount>0 ,則表達式將返回totalAllocatedMemory += amount, malloc(amount) ; 由於逗號運算符執行兩個表達式,但僅返回第二個表達式,因此該表達式的最終返回值是malloc的一個。

但是,如果它是內聯函數,則該丑陋的宏將更加清晰(並且不會造成性能損失)。

MALLOC宏與您的擴展不太相同。

如果條件為true,則三元運算符將返回調用返回的malloc指針;如果條件為false,則返回NULL指針。

只要將三元運算符的結果分配給可變變量,就不會有內存泄漏。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM