2017-08-25 10 views
-2

動的に割り当てられたオブジェクトにメンバ変数、たとえばvectorをサイズ変更するとどうなるかと思います。C++で動的に割り当てられたオブジェクト内のメンバ変数のサイズを変更

class A 
{ 
public: 
    vector<int> x; 

    void expand() 
    { 
     vector<int> y = { 1, 2, 3 }; 
     x = y; 
    } 
}; 

int main() 
{ 
    A* a = new A; 
    cout << sizeof(*a) << endl; 
    a->expand(); 
    for (auto v : a->x) 
     cout << v << endl; 
    return 0; 
} 

割り当てられたオブジェクトAのサイズが既にnewの時間によって決定されるので、未定義の動作において、この演算結果になります。例えば?割り当てが発生したときにコンパイラはxの実際のサイズを知らないので、expand()は機能しません。はいの場合、この問題からどのように回避する必要がありますか?事前に助けてくれてありがとう。

+0

異なるサイズのベクトル vの 'sizeof(v)'をチェックしてください。ベクトルは未定義の動作を使用していますか? – juanchopanza

+0

"size"は "sizeof"を意味しています。もしあなたが何をしていても、大きさは 'a'、' a'、 'a *'、 'a-> x'のいずれかに変わります。 –

+0

@Someprogrammerdude私は5回あなたのコメントを読んだが、それでも私には意味がない。サイズは変わらないでしょうか? – user3188346

答えて

0

std::vectorの実装については、コンパイラ固有の理由で難しいです。コンパイル時に不明な要素を格納することができる非常に単純なクラスです。

#include <iostream> 

class TrivialExtendableArray 
{ 
public: 
    TrivialExtendableArray() 
     : internalStorage(nullptr), 
     size(0) 
    { 

    } 

    ~TrivialExtendableArray() 
    { 
     if(internalStorage != nullptr) 
     { 
      delete []internalStorage; 
     } 
    } 

    TrivialExtendableArray(const TrivialExtendableArray&) = delete; 
    TrivialExtendableArray& operator=(const TrivialExtendableArray&) = delete; 

    int* getPointer() 
    { 
     return internalStorage; 
    } 
    size_t getSize() 
    { 
     return size; 
    } 

    void addElement(int newElementValue) 
    { 
     int* newStorage = new int[size+1]; 

     std::copy(internalStorage, internalStorage + size, newStorage); 

     if(internalStorage != nullptr) 
     { 
       delete []internalStorage; 
     } 
     newStorage[size] = newElementValue; 

     size++; 
     internalStorage = newStorage; 
    } 

    const int* begin() const 
    { 
     return internalStorage; 
    } 
    const int* end() const 
    { 
     return internalStorage + size; 
    } 

private: 
    int* internalStorage; 
    size_t size; 
}; 

std::ostream& operator<<(std::ostream& out, const TrivialExtendableArray& array) 
{ 
    out << "{ "; 
    for(const int* i = array.begin(); i != array.end(); i++) 
    { 
     out << *i << " "; 
    } 
    return out << "}"; 
} 

int main() 
{ 
    TrivialExtendableArray array; 

    std::cout << "Empty TrivialExtendableArray on stack sizeof: " << sizeof(array) << ": " << array << std::endl; 

    array.addElement(5); 

    std::cout << "TrivialExtendable with one element on stack sizeof: " << sizeof(array) << ": " << array << std::endl; 

    array.addElement(3); 

    std::cout << "TrivialExtendable with two elements on stack sizeof: " << sizeof(array) << ": " << array << std::endl; 

    array.addElement(3); 

    std::cout << "TrivialExtendable with three elements on stack sizeof: " << sizeof(array) << ": " << array << std::endl; 

} 

あなたは、私はそのような何か受け取った使用しているコンパイラおよびアーキテクチャによって異なる場合があり、このプログラムの結果:

$ ./a.out 
Empty TrivialExtendableArray on stack sizeof: 16: { } 
TrivialExtendable with one element on stack sizeof: 16: { 5 } 
TrivialExtendable with two elements on stack sizeof: 16: { 5 3 } 
TrivialExtendable with three elements on stack sizeof: 16: { 5 3 3 } 
は、クラスのサイズが原因で毎回同じである

TrivialExtendableArrayのオブジェクトは、割り当てられたメモリへのポインタとこのメモリのサイズを格納する必要があります。要素の数は、このクラスのフィールドのサイズを変更しません。

std::vectorは非常に似たアプローチを使用しています。したがって、オブジェクトを操作すると、std::vectorオブジェクトのサイズは変更されません。

関連する問題