14

と に関する 2 つのコード ブロックがありnew[]ますdelete[]

1)

#include <string>

int main()
{
  std::string *p = new std::string[0];
  delete[] p;

  return 0;
}

2)この場合、私はstd::string単にint

int main()
{
  int *p = new int[0];

  delete[] p;

  return 0;
}

私の質問は:

最初のプログラムが次のメッセージでクラッシュする理由 (Linux 環境で):

Segmentation fault (core dumped)

しかし、2 番目のプログラムはエラーなく正常に動作しますか?

編集

コンパイラ:g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2

g++引数なしでコンパイルするだけです。

それがコンパイラのバグである場合、標準に従ってクラッシュする必要がありますか?

4

1 に答える 1

13

これはgccのバグであるはずです。式全体new[]が無視されて初期化されなくpなると、初期化されdelete[]ていないポインタがクラッシュします。プログラムをコンパイルすると、次の-Wallように警告されます

警告:「p」はこの関数で初期化されていない状態で使用されます

これは明らかに間違っています。式new X[0]はC++03とC++11(§5.3.4/ 7)の両方で明確に定義されており、これはclangで正しく機能するため、論理的な結論はgccのバグであるということだけです。


バグの除去new[]は、構築される型に自明でないコンストラクターがある場合にのみ存在します。また、セグメンテーションフォールトが発生すると、型にデストラクタがdelete[]あります。これは、初期化されていないポインタを逆参照する必要があるためです。したがって、は些細なことであり、そうではないため、クラッシュしstd::stringますが、クラッシュしません。intintstd::string


これは、式を直接0に評価できないように、中間変数を使用することで回避できます。

size_t length = 0;
std::string* p = new std::string[length];
// ...
delete[] p;
于 2012-10-31T13:33:23.927 に答える