簡體   English   中英

C ++:內存泄漏

[英]C++: memory leaks

問題:變量n的值是多少,以下代碼會導致內存泄漏?

那是代碼:


int* Bar(int n)
{
  if (n == 1)
    throw "exception";
  return new int[n];
}

void Foo(int n)
{
  int *a = Bar(n);
  if (n <= 2)
    return;
  delete[] a;
}

從5.3.4 / 7開始

當direct-new-declarator中的表達式的值為零時,將調用分配函數以分配不帶元素的數組。

從3.7.3.1/2開始

取消引用作為零大小請求返回的指針的效果是未定義的。

即使[new]請求的空間大小為零,請求也會失敗。

這意味着你可以做到,但你不能合法地(在所有平台上以明確定義的方式)取消引用你得到的內存 - 你只能將它傳遞給數組刪除 - 你應該刪除它。

這是一個有趣的腳注(即不是標准的規范部分,但包含在說明性的傀儡中)附在3.7.3.1/2的句子上

[32。 目的是通過調用malloc()或calloc()來實現operator new(),因此規則基本相同。 C ++與C的不同之處在於要求零請求返回非空指針。

  • 如果n為1,我們得到:

int * a = Bar(1)和Bar(1)拋出異常。 它是變量a的構造函數中的異常嗎? 它會導致內存泄漏嗎?

如果a == 0或a == 2,它可能會導致它們。

如果a == 1則拋出異常並且沒有分配內存。 如果分配和釋放> 2個內存。

如果必須分配== 0內存,因為不允許new返回空指針。 您必須使用delete []釋放已分配的內存。

如果分配了== 2內存並且函數返回。 這是一個明顯的泄漏。

If n < 0            you'll more likely get exception std::bad_alloc (because of n will be converted to size_t which is unsigned) - no memory leak.
If n == 1           you'll get exception (invoked by `throw "exception"`) - no memory leak.
If n == 0 || n == 2 you'll never call delete - memory leak.
If n > 2            you'll call delete - no memory leak.

不,如果我正確理解你的問題,bar函數將拋出異常並且Foo函數從未實際捕獲它,這意味着它也將傳遞出該函數。 但不是它不應該導致內存泄漏,因為你在分配之前拋出。

您的評估大多是正確的 - n = 2將導致內存泄漏,n = 0理論上會導致內存泄漏 - n = 1將拋出異常(因此永遠不會執行新的int),因此沒有內存泄漏。

n> 2的任何值都不會導致內存泄漏。

現在,如果n <0 - 你有未定義的行為 - 你可能會得到一個內存泄漏(這是一個負的int可以轉換為一個大的正無符號值 - 可能會發生壞事)

由於拋出異常沒有捕手,它將繼續進行並返回。 但由於我們聲明為整數指針,如果將'n'發送為零,將創建一個默認指針。 您也可以檢查指針的大小。 但它不會導致任何內存泄漏。 后面的原因是,當你執行返回時,因為它是一個單個整數指針並且是一個局部變量,所以默認情況下釋放占用的內存。 因此,在您提到的情況下,將不會發生內存泄漏。

是的, 02會導致內存泄漏。


這也是管理動態內存的非常糟糕的做法。 在C ++上,創建一個管理內存的類是很自然/更好的方法(例如,在構造函數中它分配一些內存,在析構函數中它會釋放它)。 這將更加無泄漏且更安全

暫無
暫無

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

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