VC2008 deleteの挙動について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ねこ

VC2008 deleteの挙動について

#1

投稿記事 by ねこ » 15年前

お久しぶりです。
少々調べても分からない、というよりどう調べると良いのか分からない事が発生したので質問します。
動的にメモリを確保する際以下のように記述したとします。

int* pi = new int[ 100 ];
delete pi;

こうするとpiに代入されるポインタから「sizeof(int)*100」分のメモリが確保され、
deleteで解放されると思います。

この挙動を特に調べたわけでもなく自作するメモリ管理構造のように、ポインタアドレス等をキーに
確保したサイズとかの情報をどこかに確保しているのだと思っていました。

ところが先日とあるソース内に違和感を感じる処理がありました。上述したソースを流用して同じことを書くと

(処理1)
int* aryP[ 10 ];
for( int i = 0; i < 10; i++ )
aryP[ i ] = pi + i * 10;

(処理2)
for( int i = 0; i < 10; i++ )
delete aryP[ i ];

この処理を通るようにしても落ちたりはしなかったんですが、
たまたまなのか最適化によって上手く変換されてるのか分かりません。

処理2では確かに確保した領域のアドレスを渡してると思うのですが、
そもそもループ最初の「delete aryP[ 0 ]」でどれだけのメモリが解放されているのか・・・
そのあたりがよく分からないので質問します。

1.newで確保した情報はどのように管理されているのか
2.delete時は内部的にどのような処理が走るのか
3.1、2の管理はもしかしてコンパイラやOS依存になるのか

実行環境は
VC2008 OS WinXP Home SP3になります。

たかぎ

Re:VC2008 deleteの挙動について

#2

投稿記事 by たかぎ » 15年前

> int* pi = new int[ 100 ];
> delete pi;

これは間違いです。
正しくは、次のようにしなければなりません。

int* pi = new int[ 100 ];
delete [color=red>[ ][/color] pi;

> 1.newで確保した情報はどのように管理されているのか

Visual C++の場合、定義し直していなければ、大域的なoperator newのメモリ管理方法はmallocと同じです。

> 2.delete時は内部的にどのような処理が走るのか

配列形式のdelete式では、配列の各要素に対してデストラクタを呼び出します。
そして、メモリを解放します。
Visual C++の場合、定義し直していなければ、大域的なoperator deleteのメモリの解放はfreeと同じです。

> 3.1、2の管理はもしかしてコンパイラやOS依存になるのか

メモリの管理方法ということであれば、処理系に依存します。

ねこ

Re:VC2008 deleteの挙動について

#3

投稿記事 by ねこ » 15年前

>たかぎさん
回答ありがとうございます。

< これは間違いです。
< 正しくは、次のようにしなければなりません。
< int* pi = new int[ 100 ];
< delete [ ] pi;

忘れてました・・・そういえば配列は[/url]でした、気をつけます。


<1.newで確保した情報はどのように管理されているのか
<<Visual C++の場合、定義し直していなければ、大域的なoperator newのメモリ管理方法はmallocと同じです。
なるほど、書き方が変わるだけでmallocと変化が無いのですね

<2.delete時は内部的にどのような処理が走るのか
<<配列形式のdelete式では、配列の各要素に対してデストラクタを呼び出します。
<<そして、メモリを解放します。
<<Visual C++の場合、定義し直していなければ、大域的なoperator deleteのメモリの解放はfreeと同じです。
ということはどんどんアドレスを進めて行ってどこかで未使用領域と判定出来る何かがあるか、またはアドレスに対するサイズがあるという認識で良いのでしょうか。

<3.1、2の管理はもしかしてコンパイラやOS依存になるのか
<<メモリの管理方法ということであれば、処理系に依存します。
なるほど。ちょっと機会があれば触ってみようと思います。


自分で疑問に思ってたことは単純に「[/url]」忘れによるものな気がしてきました。
現物ソースでちゃん見れてたか不安になってきたので、再度見直してこようと思います。
見直してなお何かしら疑問に思ったら再度質問させて頂こうと思います。

ありがとうございました。

たかぎ

Re:VC2008 deleteの挙動について

#4

投稿記事 by たかぎ » 15年前

> なるほど、書き方が変わるだけでmallocと変化が無いのですね

mallocと同じなのは、メモリ管理方法だけです。
new式の動作は、大雑把にいうと次のようになります。

1. mallocでメモリを割付ける。
2. メモリの割付けに失敗した場合、set_new_handlerで登録した関数があればそれを呼び出す。そうでなければ、std::bad_alloc例外を送出する。
3. メモリの割付けに成功するまで1.と2.を繰り返す。
4. コンストラクタを呼び出す。
5. コンストラクタから例外が送出された場合、operator deleteを呼び出してメモリを解放する。

ねこ

Re:VC2008 deleteの挙動について

#5

投稿記事 by ねこ » 15年前

詳しい解説ありがとうございます。

生成時はそのような処理になっているのですね。
大変参考になりました。ありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る