2

new []とdeleteを組み合わせたり、その逆(delete []とnew)を組み合わせたりしないようにする必要があることはわかっています。それで

int* k = new int[5];
delete k;

割り当てられたアレイを解放しないため、欠陥があります。しかし、次は間違っていますか?

int *k = new int[5];
for (int i = 0; i < 5; ++i)
    delete k[i];

間違って私は意味します-それは実際にメモリリークまたは未定義の動作を引き起こしますか?

編集**私の悪い、私がタイプするつもりだったのはこれでした:

int** k = new int*[5];
memset(k, 0, sizeof(int*)*5);

k[3] = new int;

for (int i = 0; i < 5; ++i)
    if (k[i])
    {
        delete k[i];
        k[i] = 0;
    }

上記では、5つの場所のブロックは、それ自体でdelete []を呼び出さない限り、実際に解放されることはありませんがk、その中のintを新規/削除で管理できます。

4

2 に答える 2

6

k[i]はであるintため、これを呼び出すことは構文的に無効deleteです。コンパイラはエラーを発生させる必要があります。

可能であったとしても、それは未定義の振る舞いをもたらすでしょう(あなたが割り当ててnew[]それを削除しようとするポインタの配列があると言ってdelete)。と混合new[]するdeletenew[]deleteUBになります。

于 2012-12-03T21:38:31.080 に答える
3

どちらの方法でも組み合わせることができません。そうした場合、未定義の動作が発生します(§5.3.5/ 2):

最初の選択肢オブジェクトの削除)では、のオペランドの値はdelete、nullポインター値、前のnew-expressionによって作成された非配列オブジェクトへのポインター、またはベースを表すサブオブジェクト(1.8)へのポインターである可能性があります。そのようなオブジェクトのクラス(第10節)。そうでない場合、動作は未定義です。

2番目の選択肢配列の削除)では、のオペランドの値はdelete、nullポインター値、または前の配列new-expressionから得られたポインター値である可能性があります。そうでない場合、動作は未定義です。

(大胆な強調は私のものです)

于 2012-12-03T21:38:19.037 に答える