1

以下のC++コードを実装した後、valgrind --leak-check=fullメモリリークがないかどうかを確認するために実行しました。その結果、終了時に0バイトが使用され、リークは発生し ませんでした。

しかし、後で、デストラクタの内部ではdelete[] xなく、使用するのを忘れていることに気付きました。delete x

いくつかの説明(たとえば、C++のdeletevs delete []演算子)を検索しましたが、配列の最初のオブジェクトのデストラクタのみを呼び出すため、deletewithoutを使用するとメモリリークが発生する可能性があると読みました。[]

コードをdelete[]に変更しましたが、valgrindの出力は同じでした(予想どおり)。しかし今、私は混乱しています。「valgrindに問題がありますか、それともdelete演算子がなくても配列に対して実際に正常に機能します[]か?」

#include <iostream>
#include <string.h>
using namespace std;
class Foo {
  private: char *x;
  public:
    Foo(const char* px) {
       this->x = new char[strlen(px)+1];
       strcpy(this->x, px);
    }
    ~Foo() {
       delete x;
    }
    void printInfo() {  cout << "x: " << x << endl;  }
};
int main() {
   Foo *objfoo = new Foo("ABC123");
   objfoo->printInfo();
   delete objfoo;
   return 0;
}
4

2 に答える 2

7

[] なしで delete を使用すると、メモリ リークが発生します。

いいえ、Undefined Behaviorが発生します。

new []using を使用して割り当て、usingを解放するプログラムには、delete未定義の動作があります。実際、あなたはラッキーです (むしろアンラッキーです)。奇妙な動作は見られません。

補足として、クラスの 3 つのルールに従う必要もあります。現在、あなたはそうしておらず、近い将来にトラブルが発生する可能性があります。

于 2012-05-14T15:12:41.057 に答える
3

との主な違いは、メモリの解放に関するものdeletedelete[]はなく、デストラクタの呼び出しに関するものです。

正式には未定義の動作ですが、実際には多かれ少なかれ機能します...ただしdelete、最初のアイテムのデストラクタのみを呼び出します。

補足として、次のような問題が発生する可能性があります。

#include <iostream>

struct A{
  ~A() { std::cout << "destructor\n"; }
};

int main() {
  A* a = new A[10];
  delete a;
}

少し似ている:

*** glibc detected *** ./prog: munmap_chunk(): invalid pointer: 0x093fe00c ***
======= Backtrace: =========
/lib/libc.so.6[0xb759dfd4]
/lib/libc.so.6[0xb759ef89]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/libstdc++.so.6(_ZdlPv+0x21)[0xb77602d1]
./prog(__gxx_personality_v0+0x18f)[0x8048763]
./prog(__gxx_personality_v0+0x4d)[0x8048621]
======= Memory map: ========

ideoneでご覧ください。

于 2012-05-14T15:44:45.730 に答える