[596] Re:deleteとdelete[]
投稿者:774RR
2007/02/20 02:13:25
すでに完璧な答えが出てますが、一応フォローをば。
>>ところで delete と delete[] はどう違うのでしょうか。
>>両者を取り違えると不都合があるのでしょうか。
はい、言語仕様上「未定義」つまり、「誤りであり、何が起きても文句は言えない」状態です。
不都合が生じても一向に構いませんし、プログラマの期待通りに動いても構いません。
>> x=new char[n]; の後の delete[] x; でchar型のn個の領域が開放されますが
>>このときのnの値(開放すべきデータのサイズ)は
>>メモリのどこに保存されているのでしょうか。
言語仕様は何も定めていません。なのでまさに
>「どこかの管理領域」としか言いようがないです
が、実装を簡単にするために、こんな手が使われることが多いです。
T* p=new T[n]; は内部で
struct anonymous_n_array_of_T {
size_t n; // この n の前後に padding が入ることもあります
T array[n];
};
anonymous_n_array_of_T* p0=malloc(sizeof(anonymous_n_array_of_T));
p0->n=n;
return &p0->array[0];
同様 delete[] p; の内部処理は
anonymous_n_array_of_T* p0=translate_pointer(p); // get p-sizeof(size_t)
for (int i=p0->n; i>=0; --i) explicit_destructor_call(&p0->array[i]);
free(p0);
// 説明のためにいろいろ略:キャストの明示など
よって new/delete[] や new[]/delete をしてしまうと、正しく配列要素数が取り出せず
誤動作してしまうのです(デストラクタが呼ばれすぎ・呼ばれないなど)=未定義動作
VC++ など一部のコンパイラでは POD (plain old data) 型 (char/int など) の
new[]/delete[] が単純な malloc/free になっているので
new[] を delete しても動いてしまい、問題が発覚しにくくなっています。
その昔、開発中の C++ では delete[n]p; と要素数の指定が必要でした。
これはあまりもアレげなので現在の仕様になった、と D&E にあります。