2016-08-16 16 views
1

私はこのC++構造を有する:私は次のがかかりますどのくらいのメモリ見つけるためにしようとしている要素を追加するとベクトルのサイズが同じになるのはなぜですか?

typedef unsigned long T; 

struct Node { 
    T index; 
    T length; 
    Node(): index(0), length(0), next(0) {} 
    Node(const T &ind, const T &len): index(ind), length(len), next(0) {} 
    vector<Node*> next; 
}; 

を。私はそれが最大5つの要素を持つことを知っています。だからここに私は何をすべきかです:

int main(int argc, const char * argv[]) { 

    Node n; 
    Node* x = new Node(3, 4); 

    cout << "An empty vector of pointers: " << sizeof(n.next) << " bytes\n"; 

    // Add five elements 
    for(int i = 0; i < 5; i++) 
     n.next.push_back(x); 

    cout<< "New size of the vector of pointers: " << n.next.size() << " elements\n"; 
    cout<< "New size of the vector of pointers: " << sizeof(n.next) << " bytes\n"; 

    return 0; 
} 

そして、ここでは私の出力です:

An empty vector of pointers: 24 bytes 
New size of the vector of pointers: 5 elements 
New size of the vector of pointers: 24 bytes 

私の質問:どのように空のベクターは、5と24のバイトが、同じベクトルを取ることも可能ということです要素はまだ24バイトかかりますか?それ以上の記憶を取るべきではありませんか? * 24 + 5 * sizeof(Node *)*のように?

+3

'int * x = new int [1]; int * y =新しいint [100] '。なぜ、sizeof(x)== sizeof(y) 'というのは、異なるサイズの配列を指していても、考えてみてください。 –

+0

どちらの場合でもポインタのサイズは? – alekscooper

+0

ベクトルがどのくらいのメモリを使用しているか知る必要がある場合は、正確にどのくらいの量のメモリが必要かを知る必要がある場合は、 'sizeof(n.next)+ n.next.capacity()* sizeof(Node *);ベクトルが割り当てられた場合は、独自のアロケータをベクターに与えます。 – evan

答えて

1

あなたはn.next.size()が必要です。

sizeofは、1つのインスタンスを格納するために必要なバイト数を把握するためだけに型を調べるため、完全にコンパイル時の操作です。 sizeof(n.next)は、n.nextを保持するために必要なバイト数を示します。 vectorであるため、3つのポインタ(それぞれ8バイト)を使用して実装されている可能性があります.1つは割り当てられた配列の先頭を指し、1つはデータの最後を指し、1つは割り当てられた配列の最後を指します。

+0

いいえ、私はそれがいっぱいになるときに私の次のは、どのくらい多くのバイトを知ってほしい、それはそこにノードへの5つのポインタがあることを意味します。しかし、私はそれをどのように計算するのか分かりません。 – alekscooper

+0

@alekscooper実際にメモリ使用量を厳密に追跡する必要がある場合は、間違ったプログラミング言語を使用しています。何が起こっているか知りたいのであれば、http://stackoverflow.com/questions/910172/track-c-memory-allocationsを参照してください。 –

4

Vectorは、通常は動的に割り当てられたデータへのポインタを含む固定「フットプリント」を持つ動的構造です。

n.next.size()は、動的に割り当てられたデータのサイズを返します。 sizeof(n.next)は固定フットプリントのサイズを返します。

2

すべてのオブジェクトは同じサイズで、sizeof(n.next)sizeof(vector<Node*>)に相当します。

vectorインスタンスには要素が含まれていないため、インスタンス自体が指しているだけなので、インスタンス自体は常に同じサイズです。

それは、まさにこのように動作します:

class A 
{ 
public: 
    A(int n) : p(new char[n]), s(n) {} 
    int size() const { return s; } 
private: 
    char* p; 
    int s; 
}; 

int main() 
{ 
    A a(1); 
    A b(100); 
    // These all print the same thing: 
    std::cout << sizeof(a); 
    std::cout << sizeof(b); 
    std::cout << sizeof(A); 
    // These are different: 
    std::cout << a.size(); // Prints 1 
    std::cout << b.size(); // Prints 100 
} 

あなたのベクトルは、合計で占めているどのくらいのスペースを知りたい場合は、あなたがいることを自分で計算する必要があります。

1

標準として提供されるベクターの実装は、通常、必要な容量以上のもので寿命を開始するように最適化されています。簡単に言えば、インプリメンテーションでは、たとえ少数であってもベクトルを配置するスペースを計画しています。この数を超えると、さらに多くのメモリを割り当て始めます。

これは決してこれらの要素を使用しない場合は少量のメモリを消費しますが、追加する各要素のメモリを再割り当てする際のパフォーマンスのオーバーヘッドはなくなります。正確な金額は実装に依存しますが、そうでない場合もありますが、典型的な最適化です。

要素が使用する領域を測定する場合は、より多くの量を必要とします。たとえば、100個のオブジェクトを入れてチェックし、200を入れてチェックします。少量の場合は、しきい値に達するまで一定のサイズが表示されます。

+0

私は、メモリの面でより効率的なことを知りたいresources:構造体の各インスタンスがそのベクトルに正確に5つのポインタを持つわけではないが、ポインタのベクトルを持つ構造体として持つこと。 Node * next [5]のような5要素の固定長配列を持つ構造体を持つことができます。 – alekscooper

+0

5の固定配列は、純粋なメモリバイトカウントでより効率的になります。常に。しかし、ベクトルを使用することによるオーバーヘッドは、何百万ものものがある場合を除いて、小さくて過失です。ベクターが提供するものを処理するために必要な余分なコードは、このような節約になります。また、配列を使用すると、ベクトルが回避するエラーの機会が増えます。したがって、一言で言えば、ベクトルはおそらく20%のメモリオーバーヘッドを持っていますが、膨大な量が必要な場合を除き、依然としてより良い選択です。 – Aganju

関連する問題