1

次のコードで、最後に予想される出力が実際の出力と異なるのはなぜですか?

#include<iostream>
#include<fstream>
#include<istream>
#include<sstream>
#include<vector>

using namespace std;


int main()
{
        vector<int> v;
        for(int ii = 0; ii < 4; ii++){
            v.push_back(0);
        }

        vector<vector<int>> twoDv;

        for(int ii = 0; ii < 5; ii++){
            twoDv.push_back(v);
        }

        cout<<"Expected Output : " << &twoDv[0][0] <<'\t'<< (&twoDv[0][0] + 3) <<'\t'<< (&twoDv[0][3] + 1)<<'\n';
        cout<<"Actual Output   : " << &twoDv[0][0] <<'\t'<< &twoDv[0][3] <<'\t'<< &twoDv[1][0] << '\n';
}
4

3 に答える 3

5

vector< vector< int > >のような 2 次元配列ではありませんint[5][5]。配列へのポインタの配列です。(より正確には、std::vector整数へのポインターを含むオブジェクトのシーケンスが含まれます。)「行」​​のみが連続しています。異なる行は、別の malloc されたメモリ ブロックに格納される可能性があるため、互いに連続していません。

于 2012-11-12T09:39:46.493 に答える
5

Avectorはその要素を連続メモリに格納します。ただし、 の要素はvector<vector<int>> twoDv;int ではなくベクトルであり、int はvector ごとに内部的に連続メモリに格納されます。

ここに画像の説明を入力

ポインタの配列を考えてみましょう:

int* x[10];

10ポインタは連続メモリに保存されますが、ポインタが指すものは連続メモリにある必要はありません。

于 2012-11-12T09:41:11.563 に答える
2

&twoDv[1][0]標準では、それがに等しいとは言われていません&twoDv[0][3] + 1。それはに&twoDv[1]等しい&twoDv[0] + 1、そしてそれ&twoDv[0][1]はに等しいと言い&twoDv[0][0] + 1ます。

に等しい瞬間が&twoDv[1][0] あった&twoDv[0][3] + 1としましょう、そしてあなたはそうしましたtwoDv[0].resize(5);。突然、競合が発生しました。のアドレスになること、のアドレスに&twoDv[0][3] + 1なることもできません。したがって、のサイズ変更操作では、イテレータと別のベクトルの要素への参照を無効にする必要があります。これは非常に望ましくない動作です。&twoDv[1][0]&twoDv[0][4]twoDv[0]twoDv[1]

于 2012-11-12T09:42:09.040 に答える