4

質問: 変数n のどの値で、次のコードはメモリ リークを引き起こしますか?

それがコードです:


int* Bar(int n)
{
  if (n == 1)
    throw "exception";
  return new int[n];
}

void Foo(int n)
{
  int *a = Bar(n);
  if (n <= 2)
    return;
  delete[] a;
}

5.3.4/7から

direct-new-declarator の式の値が 0 の場合、要素のない配列を割り当てるために割り当て関数が呼び出されます。

3.7.3.1/2から

サイズ 0 の要求として返されたポインターを逆参照した場合の影響は未定義です。

また

[新規によって] 要求されたスペースのサイズがゼロであっても、要求は失敗する可能性があります。

つまり、それを行うことはできますが、合法的に (すべてのプラットフォームで明確に定義された方法で) 取得したメモリを逆参照することはできません。配列の削除にのみ渡すことができ、削除する必要があります。

以下は、3.7.3.1/2 の文に付けられた興味深い脚注です (つまり、標準の規範的な部分ではありませんが、説明目的で含まれています)。

[32。その意図は、malloc() または calloc() を呼び出すことによってオペレーター new() を実装できるようにすることなので、ルールは実質的に同じです。C++ は、null 以外のポインターを返すためにゼロ要求を必要とする点で C とは異なります。]

  • n が 1 の場合、次のようになります。

int *a = Bar(1) および Bar(1) は例外をスローします。変数 a のコンストラクタで例外になるのでしょうか? そして、それはメモリリークを引き起こしますか?

4

6 に答える 6

7

== 0 または == 2 の場合に発生する可能性があります。

== 1 の場合、例外がスローされ、メモリは割り当てられません。> 2 のメモリが割り当てられ、解放されている場合。

== 0 の場合、 new は null ポインターを返すことが許可されていないため、メモリを割り当てる必要があります。delete[] で割り当てられたメモリを解放する必要があります。

== 2 メモリが割り当てられ、関数が戻る場合。明らかな漏れです。

于 2009-07-16T11:04:25.067 に答える
2
n < 0 の場合、例外 std::bad_alloc が発生する可能性が高くなります (n は符号なしの size_t に変換されるため) - メモリ リークはありません。
n == 1 の場合、例外が発生します (`throw "exception"` によって呼び出されます) - メモリ リークはありません。
n == 0 || の場合 n == 2 削除を呼び出すことはありません - メモリリーク。
n > 2 の場合、delete を呼び出します - メモリ リークはありません。
于 2009-07-16T11:18:38.080 に答える
0

はい、メモリリークが発生0します。2


また、これはそのような動的メモリを管理するための非常に悪い習慣です。C++ では、メモリを管理するクラスを作成する方がはるかに自然で優れた方法です (たとえば、コンストラクタでメモリを割り当て、デストラクタでメモリを解放します)。これにより、より漏れがなく、より安全になります

于 2016-08-15T13:37:02.253 に答える
0

いいえ、あなたの質問を正しく理解していれば、 bar 関数は例外をスローし、 Foo 関数は実際にはそれをキャッチしません。つまり、その関数からも渡されます。ただし、割り当てが行われる前にスローするため、メモリリークが発生することはありません。

于 2009-07-16T11:06:16.403 に答える
0

あなたの評価はほとんど正しいです-n = 2はメモリリークを引き起こし、n = 0は理論的にメモリリークを引き起こします-n = 1は例外をスローします(新しいintは実行されません)ので、メモリリークはありません.

n > 2 の値を指定しても、メモリ リークは発生しません。

n < 0 の場合 - 未定義の動作が発生し、メモリ リークが発生する可能性があります (つまり、負の int が大きな正の unsigned 値に変換される可能性があり、悪いことが起こる可能性があります)。

于 2009-07-16T11:14:24.547 に答える
0

スローされた例外にはキャッチャーがないため、さらに進んで戻ります。ただし、整数ポインターとして宣言したため、「n」をゼロとして送信すると、デフォルトのポインターが作成されます。ポインタのサイズも確認できます。ただし、メモリリークは発生しません。背後にある理由は、リターンを行うと、それは単一の整数ポインターであり、ローカル変数であるため、占有されているメモリはデフォルトで解放されます。したがって、あなたが言及した場合に発生するメモリリークはありません。

于 2009-07-16T11:14:50.350 に答える