1

この例では、1つの整数を含むベクトルを作成してから、その整数をベクトルから消去します。ベクトルのサイズは小さくなりますが、整数はまだそこにあります!なぜ整数がまだそこにあるのですか?サイズ0のベクトルに要素を含めるにはどうすればよいですか?

#include <vector>
#include <iostream>

using namespace std;

int main(int agrc, char* argv[])
{
    vector<int> v;
    v.push_back(450);

    cout << "Before" << endl;
    cout << "Size: " << v.size() << endl;
    cout << "First element: " << (*v.begin()) << endl;
    v.erase(v.begin());
    cout << "After" << endl;
    cout << "Size: " << v.size() << endl;
    cout << "First element: " << *(v.begin()) << endl;

    return(0);
}

出力:

Before
Size: 1
First element: 450
After
Size: 0
First element: 450
4

5 に答える 5

10

無効なメモリ位置を逆参照することにより、未定義の動作を呼び出しています。通常、ヒープマネージャはdelete、効率を上げるために使用して削除されたメモリをすぐに解放しません。ただし、これは、そのメモリ位置にアクセスできることを意味するわけではありません。ヒープマネージャは、いつでもこのメモリ位置を他の目的に使用できます。したがって、無効なメモリ位置を逆参照すると、プログラムは予期しない動作をします。

于 2011-03-23T06:37:09.353 に答える
3

IIRCベクトルは、特に指示されない限りスペースを解放しません。そのため、まだメモリ内にあるが、ベクトルによって追跡されていないアイテムが表示されます。これは、最初にサイズをチェックすることになっている理由の一部です(もう1つは、何も割り当てなかった場合、ガベージポインターを逆参照することになるということです)。

于 2011-03-23T06:38:53.653 に答える
1

まず、すべてのシステムでこのようになっていることを期待しないでください。ベクトルが内部でどのように機能するかは、完全に実装に依存します。無効なメモリ位置を間接参照することにより、ドキュメントで概説されている動作を回避しています。つまり、STLドキュメントで概説されている動作動作のみを期待できます。

そのメモリ位置に引き続きアクセスできる理由は、使用している特定の実装がメモリをすぐに削除するのではなく、しばらくの間(おそらくパフォーマンスの目的で)保持するためです。別の実装では、作成者が希望する場合、そのメモリをすぐに削除できます。

于 2011-03-23T06:44:35.170 に答える
0

ベクトルがメモリを解放していないだけで、将来の使用のためにメモリを保持しています。

これは、私たちが「未定義動作」と呼んでいるものです。次回動作するという保証はなく、将来の試行でプログラムが簡単にクラッシュする可能性があります。しないでください。

于 2011-03-23T06:41:12.667 に答える
0

コンパイラのオプションは何ですか?私が定期的に使用している両方のコンパイラ(g++とVC++)で、通常のオプションでクラッシュが発生します。g ++の場合、この動作のためにいくつかの追加オプション(-D_GLIBCXX_DEBUG、私は思う)を設定する必要があります。私の知る限り、これはVC++のデフォルトです。(VC ++に対する私のコマンドは、「cl / EHsbounds.cc」でした。)

他の人が言っているように、これは未定義の動作ですが、優れたコンパイラを使用すると、プログラムをクラッシュさせるように定義されます。

于 2011-03-23T11:56:38.960 に答える