2

以下のコードから無効なポイント エラーが発生します。理由がわかりません。私がやろうとしているのは、ベクターからヒープ上の空き文字列を削除することだけです:

void func() {
    vector<string>* vec = new vector<string>;
    vec->push_back(*(new string("1")));
    vec->push_back(*(new string("2")));

    for(vector<string>::iterator itr = vec->begin(); itr != vec->end(); ++itr)
    {
        string* ptr = &(*itr);
        delete(ptr);
    }
}

編集: push_back が文字列のコピーを作成するためですか?

4

3 に答える 3

6

エラーは、要素が動的に割り当てられていないためです。ベクトルはです。あなたがやろうとしていることは以下を必要とするでしょう:

void func() 
{
    vector<string*> vec;
    vec.push_back(new string("1"));
    vec.push_back(new string("2"));

    for(vector<string*>::iterator itr = vec.begin(); itr != vec.end(); ++itr)
    {
        string* ptr = *itr;
        delete(ptr);
    }
}

しかし、正直なところ、これを行う理由はほとんどありません。記述されたとおり、コードは実際に割り当てられなかったメモリを削除しようとするだけでなく、割り当てた内容をリークます。

このようなベクトルにオブジェクトへのポインターを格納する理由があります(オブジェクトが実際には別の場所にある別のコンテナーからのものであり、元のコンテンツを乱さずにカスタムソート操作を行うためにオブジェクトの一時的なリストが必要な場合など)が、何かが教えてくれますあなたはそのような必要性を持つことからの道です。

于 2013-02-22T19:33:32.917 に答える
4

まず、ライン

vec->push_back(*(new string("1")));

メモリリークを引き起こしています。から返される値はnew string("1")、新しく割り当てられた文字列オブジェクトへのポインターです。ただし、逆参照してベクターに挿入すると、ヒープ割り当てオブジェクトのコピーが作成されて挿入されます。ただし、最初にヒープに割り当てた実際の文字列オブジェクトはリークされます。

基本的に、ベクトルは文字列オブジェクトへのポインターではなく、文字列オブジェクトを値で格納しています。ベクトルに挿入される文字列オブジェクトのコピーは、ヒープに割り当てられたオブジェクトではありません (で割り当てられたオブジェクトではありませんnew)。もちろん、 でdelete割り当てられていないものは使用できませんnew。したがって、呼び出すdelete(ptr)と、未定義の動作が発生します。

ここで欲しいと思われるものは次のとおりです。

vector<string*>* vec = new vector<string*>;

ただし、一般的に、すべてをヒープに割り当てる説得力のある理由はわかりません。C++ では、ヒープ割り当てが必要な何らかの理由 (たとえば、ポリモーフィック オブジェクトのコンテナーなど、とにかくスマート ポインターを使用する必要がある場合) がない限り、可能な限りスタック割り当てと値セマンティクスを備えたコンテナーを使用することをお勧めします。一般に、新しい C++ プログラマーがヒープ割り当てオブジェクトとnewキーワードを至る所で使用する場合、Java や C# などのマネージ言語からインポートされたプログラミング スタイルの音訳が不十分であることを示しています。

于 2013-02-22T19:34:46.373 に答える
3

いいえ、そうではありません。ベクトルにはstring、オブジェクトへのポインタではなく、オブジェクトが格納されstringます。*これが、呼び出しにが含まれている理由ですpush_back。返されたポインターを逆参照しています。

作成した動的文字列のコピーを追加すると、返さnewれるポインタを格納しないため、その動的文字列は失われnewます。

于 2013-02-22T19:33:10.870 に答える