簡體   English   中英

C ++標准庫上的sizeof()

[英]sizeof() on C++ Standard Library

我很好奇並在一些C ++標准庫類上應用了sizeof()運算符。 這是我觀察到的:

int main() 
{
    vector<double> v1;
    set<double> s1;
    map<double,double> m1;

    stack<char> st;
    queue<char> q;

    vector<char>  v2;
    set<char> s2;
    map<char,char> m2;

    cout<<sizeof(v1)<<" "<<sizeof(s1)<<" "<<sizeof(m1)<<endl;
    cout<<sizeof(v2)<<" "<<sizeof(s2)<<" "<<sizeof(m2)<<endl;
    cout<<sizeof(q)<<" "<<sizeof(st)<<endl;
    return 0;
}

我的系統(64位)上的輸出是:

12 24 24
12 24 24
40 40

我知道std::set使用Red-Black樹來實現。 所以二叉樹的每個節點都有兩個指針(每個8個字節),值(8個字節,總共24個)似乎沒問題。

  1. std::map (也使用Red-Black樹)有一個額外的鍵,但仍然是24個字節? 為什么?

  2. 為什么std::queuestd::stack占用40個字節,而std::vector只占用12個字節?

  3. 為什么chardouble不會影響類的大小? 是因為模板嗎?

這些類的實現是一個黑盒子,沒有辦法告訴它們包含哪些數據或私有成員。 這完全取決於實施。

了解對象實例中所有字節的唯一方法是讀取源代碼。

sizeof運算符將為您提供類型的大小。

現在,如果我要在這里制作一個非常簡化的std::vector<T>版本(請注意,這並不像REAL實現那樣做任何事情,並且它太簡單而不能真正起作用 - 而且我是跳過你真正需要的很多比特):

template<typename T>
class vector<T>
{
   public:
      typedef size_t size_type;
   private:
     T* mdata;
     size_type msize;
     size_type mreserved;
   public:
     vector() { mreserved = msize = 0; mdata = 0; }
     vector(size_type sz) { msize = 0; mreserved = sz; mdata = new T[sz](); }
     void push_back(const T& v) 
     { 
        if (msize + 1 > mreserved) grow(mreserved * 2);
        mdata[msize+1] = v;
        msize++;
     }
     size_type size() const { return msize; }
     // bunch of other public functions go here. 
   private:
     void grow(size_type newsize)
     {
        if (newsize < 8) newsize = 8;
        T* newdata = new T[newsize]; 
        for(size_type i = 0; i < msize; i++) newdata[i] = mdata[i];
        swap(mdata, newdata);
        delete [] mdata;
        mreserved = newsize;
     }
  };

如您所見,無論存儲的數據集有多大,實際類的大小都是相同的(它包含相同的大小和元素數)。 換句話說, sizeof(vector<int>)是常量。 存儲在mdata后面的數據大小當然在變化,但sizeof不知道(不知道)那個。

此示例源代碼將為您提供以下想法:

struct A
{
    int* p; //4 bytes
    A(int n)
    {
        p = new int[n];
    }  
};

int main()
{
    A x1(10);   
    A x2(100);  
    cout << boolalpha << (sizeof(x1) == sizeof(x2)); //prints true
}

原因是A只包含一個指針。 指針的大小始終相同(通常為4)。 指針指向的是什么 - 動態數組1000或1000000.它仍然是4。

char或double不會影響大小,因為指向char的指針與指向double的指針具有相同的大小。

對於實際擁有數組而不是指針的std :: array,這些都很重要(數組類型和大小):

cout << boolalpha << ((sizeof(std::array<int, 10>) == sizeof(std::array<int, 11>)); //false!
cout << boolalpha << ((sizeof(std::array<int, 10>) == sizeof(std::array<long double, 10>)); //false!

重要的是要記住sizeof 在編譯時進行評估 :因此它在任何意義上都不是動態的。

它的工作是返回類/結構/普通舊數據的大小; 沒有其他的。

這就是為什么它總是為你的矢量,集合和地圖提供相同的結果。

您似乎假設容器類的大小可以隨着消耗的元素數量而增加,但這在物理上是不可能的,因為所有類型都具有固定大小。

而是使用動態分配間接存儲元素;
sizeof 不會向您透露此信息

sizeof給你的唯一信息是在容器的構造和管理中使用了多少指針,計數器,標志和其他元數據; 這種細節是從你身上抽象出來的,你永遠不應該試圖對它進行合理化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM