簡體   English   中英

新的char上的C ++ delete [];

[英]C++ delete[] on new char;

請考慮以下代碼:

int main()
{
    char* str = new char; 
    str[0] = 'a'; 
    delete[] str; //Notice the []
}

它編譯,運行並且沒有崩潰(VC15和g ++)它確實有1個內存泄漏,我可以用valgrind清楚地看到它。

但是,如果我運行以下代碼:

#include <iostream>

class Foo{
public:
    Foo(){
        std::cout << "Foo::Foo" << std::endl;
    }
    ~Foo(){
        std::cout << "Foo::~Foo" << std::endl;
    }
};

int main()
{   
      Foo* foo = new Foo;
      delete[] foo;
      return 0;
}

在Windows上運行時,我得到一個無限循環的析構函數調用,在Linux中運行一個無效的指針錯誤(在~20 d調用之后)。

我無法弄清楚為什么兩者之間存在差異? 為什么我沒有new char或崩潰的無限循環?

你應該使用delete[]和僅使用new[]分配的指針;

問題

在您的第一個代碼段中:

  • 用語句char* str = new char; 你得到一個指向單個字符的指針。 所以new的類型匹配char*
  • 但是你的delete[]需要一個指向char數組的指針,所以當你刪除一個不是數組的東西時會得到未定義的行為(UB)

第二個代碼段具有完全相同的問題。 UB未定義,可以給出奇怪和無法解釋的結果。

怎么解決?

對單個元素分配使用單個元素delete:

  Foo* foo = new Foo;
  delete foo;

或者使用數組刪除進行數組分配:

  Foo* foo = new Foo[1];
  delete[] foo;

或者更好:擺脫任何你想要使用的新/刪除並使用向量而不是數組。

為了簡化這一點,對於未使用new[]分配且不為null的指針調用delete[]始終是未定義的

我引用cppreference.com

由delete [] - 表達式調用,以釋放先前為對象數組分配的存儲。 除非ptr是空指針或者是先前從operator new或operator new [](size_t,std :: nothrow_t)的標准庫實現獲得的指針,否則此函數的標准庫實現的行為是未定義的

暫無
暫無

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

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