1. ホーム
  2. c++

[解決済み] delete[]が配列であることをどうやって知るのですか?

2022-05-11 04:52:36

質問

さて、次のコードで何が起こるかは、渡されたものによって未定義であることに、私たちは皆同意すると思います。

void deleteForMe(int* pointer)
{
     delete[] pointer;
}

ポインタはいろいろなものが考えられるので、無条件に delete[] を実行することは未定義です。しかし、実際に配列ポインタを渡していると仮定してみましょう。

int main()
{
     int* arr = new int[5];
     deleteForMe(arr);
     return 0;
}

質問ですが、この場合、ポインタの である場合、それを知っているのは誰なのでしょうか?つまり、言語/コンパイラから見て、それが arr が配列へのポインタなのか、それとも単一の int へのポインタなのか、全くわからないのです。ヘック、それは arr が動的に作成されたかどうかもわかりません。それでも、もし私が代わりに次のようにしたら。

int main()
{
     int* num = new int(1);
     deleteForMe(num);
     return 0;
}

OS は賢いので、1 つの int を削除するだけで、その先のメモリの残りを削除してある種の「殺し合い」に走ることはありません (対照的なのは strlen と非 \0 -で終端しない文字列の場合 -- 0になるまで進み続けます)。

では、これらのことを記憶するのは誰の仕事なのでしょうか?OS はバックグラウンドで何らかの記録を保持しているのでしょうか? (つまり、何が起こるかは未定義であると言うことからこの投稿を始めたことは承知していますが、事実は、「殺しまくる」シナリオは起こらないので、したがって、現実の世界では 誰か は記憶しているのです)。

どのように解決するのですか?

コンパイラはそれが配列であることを知らない、プログラマを信頼している。 ポインタを削除すると、1つの int と共に delete [] を使用すると、未定義の動作になります。 2番目の main() の例は、たとえすぐにクラッシュしないとしても、安全ではありません。

コンパイラはどのように多くのオブジェクトが削除される必要があるかを追跡する必要があります。 これは、配列のサイズを保存するために十分な量を過剰に割り当てることによって行われるかもしれません。 詳細については C++ スーパー FAQ .