3

編集:答えてくれてありがとう!tellSomethingメソッドを戻り値の型で宣言しましたが、std::stringそうである必要がありますvoid

私はつまずいて、罪のないかわいそうなdeleteオペレーターのせいにしました:)!


vector動的に割り当てられたオブジェクトへのポインターを含む、動的に割り当てられたオブジェクトへのポインターを考えてみましょう。

// Create the vector of pointers
std::vector<A *>* v = new std::vector<A *>;

// Create two objects
A *a1 = new A;
A *a2 = new A;

// Populate the vector
v->push_back(a1);
v->push_back(a2);

// Delete the vector
delete v;

// Try accessing one of the objects
a1->tellSomething();    --> // Segmentation fault

予想どおり、 を削除するvectorと、delete含まれているオブジェクトの は呼び出されません (上記のコードで が呼び出されないことも確認しA::~A()ました) が、最後の命令でセグメンテーション エラーが発生します。

私が期待するのdelete vは、次の 2 点です。

  • 含まれているすべてのオブジェクトのデストラクタが呼び出されます
  • コンテナの割り当てが解除されました

ただし、この場合、含まれているオブジェクトはポインターであるため、デストラクタは呼び出されません。

また、リストの最後にa1はありません。NULL

では、なぜセグメンテーション違反なのでしょうか?


ここに完全な例があります: http://ideone.com/r8YC0


注: 通常、STL コンテナーで生のポインターを使用することはありません。このコードは、delete v命令のロジックを理解するのに役立つ純粋に理論的な例と考えてください。

4

5 に答える 5

9

発生するクラッシュはまったく関係ありません。tellSomethingを返すと宣言しましたstd::stringが、何も返さないため、未定義の動作ランドに入ります。ベクトルの割り当てを解除した後にプログラムがクラッシュしたという事実はまったくの幸運であり、tellSomething.

その問題を修正すると、プログラムが正常に実行されます (ただし、リークa1a2.

ところで、これはすべての警告を有効にすることを教えてくれます:-Wallそのコードを使用すると、この潜在的な問題について明示的な警告が表示されます:

matteo@teolapmint ~/cpp $ g++ -Wall testwarns.cpp 
testwarns.cpp: In member function ‘std::string A::tellSomething()’:
testwarns.cpp:12:5: warning: no return statement in function returning non-void [-Wreturn-type]

(記録のために: 個人的には でコンパイルすることをお勧めします-Wall -Wextra -ansi -pedantic。多くの場合、1 つの警告でデバッグ時間を大幅に節約できます)。

于 2012-07-24T19:16:59.997 に答える
8

std::stringクラッシュは、無効なデストラクタへの呼び出しが試みられたことが原因です。

std::string tellSomething() {
    std::cout << "A!" << std::endl;
}

への呼び出しa1->tellSomething();は、ランタイムにスコープ内の自動ストレージを期待するように指示しstd::string、それを破棄しようとします。しかし、それは無効です。

技術的には、これは未定義の動作です。約束したものを返していないためです。

于 2012-07-24T19:16:46.440 に答える
3

ベクトルを削除しても、ベクトル要素は削除されません。文字列を返すように指定されているときに、tellSomething() が値を返さないことが原因で発生する、まったく別の問題が発生しています。

http://ideone.com/Jo9zi

于 2012-07-24T19:17:11.213 に答える
3

メソッド内のリンクされたコードでは、実行していないものA::tellSomethingを返す必要std::stringがあるため、クラッシュします。削除とか関係ないv

于 2012-07-24T19:17:15.333 に答える
2

tellSomethingメソッドに戻り値がありません。

そのメソッドにa を追加するreturn "";と、メモリ リークは発生しますが、コードは正常に実行されます。

于 2012-07-24T19:16:23.837 に答える