2

私は例に出くわしました:

#include <iostream>
#include <stdexcept>

using namespace std;

class A{
public:
    A():m_n(m_object_id++){}
    ~A(){cout << m_n;}
private:
    const int m_n;
    static int m_object_id;
};

int A::m_object_id=0;


int main()
{
    A * const p = new A[3];
    A * const q = reinterpret_cast<A * const> (new char[3*sizeof(A)]);
    new (q) A;
    new (q+1)A;
    q->~A();
    q[1].~A();
    delete [] reinterpret_cast<char *>(q); // -> here
    delete[] p;
    cout << endl;

    return 0;
}

出力: 34210

誰かが説明できますかdelete [] reinterpret_cast<char *>(q); // -> here、それが何をしていて、出力を生成していますか?

編集

私の質問は、delete [] reinterpret_cast<char *>(q);なぜ~A(){cout << m_n;}そうdelete[] p;ですか?

4

4 に答える 4

3

delete []配列のすべての要素に対してデストラクタを呼び出し、関連するメモリを解放します。delete配列へのポインタで最初の要素のデストラクタを呼び出すだけで、関連するすべてのメモリを解放します。

delete []を使用するときは必ず使用してくださいnew [..]

delete呼び出されるデストラクタは、またはに渡されるポインタの型によって決まりますdelete []。以下のサンプルでは:

A *object1 = new A();
B *object2 = new B();

delete (B*) object1;
delete (A*) object2;

~B()のインスタンスで呼び出されているため、(潜在的に) すべての地獄が解き放たれますA

void *object = new A();
delete object;

のインスタンスへのポイントが~A()わからないため、 は呼び出されませんが、objectA

void *object = new A();
delete reinterpret_cast<A*>(object);

~A()関連するメモリを解放する前に正しく呼び出します。

于 2013-06-28T01:51:09.573 に答える
2

qは のメモリで初期化new char[3*sizeof(A)]されていますが、 の配列として扱われていAます。このメモリはnew、その配列の最初の 2 つの要素の配置を実行するために使用されます。

A * const q = reinterpret_cast<A * const> (new char[3*sizeof(A)]);
new (q) A;
new (q+1)A;

構築された要素のデストラクタを明示的に呼び出した後、qは にキャストバックされchar *、メモリは で削除されdelete []ます。キャストの目的は、which へdelete[]の呼び出しで作成されたのと同じタイプのオブジェクトに が適用されていることを確認することです。new[]q

q->~A();
q[1].~A();
delete [] reinterpret_cast<char *>(q); // -> here

で割り当てられたオブジェクトのコレクションはnew[]、 で削除する必要がありますdelete[]。これはdelete[]、ポインタを配列割り当てとして扱い、各配列要素を適切に破棄するためです。

于 2013-06-28T01:56:11.610 に答える
1

new char[3*sizeof(A)]「3 As に十分な大きさのスペースを割り当ててください。ただし、そのスペースは char 配列/文字列と考えてください。」

reinterpret_cast<A * const>割り当てたばかりのメモリのブロックを文字列と考えて、それを As の配列と考えます。

delete [] reinterpret_cast<char *>(q);Asの配列として考えているメモリのブロックを取り、それを再び配列charとして考え始めます. (つまり、delete[] は、A dtor ではなく、その配列内の各文字の文字 dtor を呼び出します)

実際のコードでそのようなことをしないでください!

于 2013-06-28T01:54:52.240 に答える
0

p はクラス A の単純な配列として割り当てられ、後で削除されます。q は生メモリとして割り当てられ、配置 new を使用してその生メモリ内に A の 2 つの要素が作成されるため、より複雑です。これらの 2 つの要素は個別に削除され、生のメモリは質問しているステートメントによって削除されます。

于 2013-06-28T01:57:33.400 に答える