zoukankan      html  css  js  c++  java
  • c++ 对象大小内存占用分析

    由于是64位机器,因此以下分析中指针都是占用64位

    #include<bits/stdc++.h>
    using namespace std;
    
    // 1 空类对象
    // sizeof emptyObj=1
    class emptyClass{};
    
    // 2 普通成员函数对象
    // sizeof generalObj = 1
    class hasGeneralFuntionClass{
        public:
        void show(){ cout<<" show()"<<endl;}
    };
    
    // 3 虚函数对象: 虚指针占用对象的内存空间
    // sizeof virtualObj = 8
    class hasVirtualFunctionClass{
        public:
        virtual void show(){cout<<"show()"<<endl;}
    };
    
    // 4 结构体对象
    // 结构体对齐三条原则
    // 1 首个成员从地址0开始
    // 2 每个成员的首地址是自身大小的整数倍,不满足的地址需要填充,
    //   即:如果当前成员大小为m字节,一定以m的倍数开始的地址存放该成员。
    // 3 结构体整体补齐。
    //   即:如果结构体最大成员是n字节,则最后的结构体大小一定是n的倍数,不满足的填充。
    
    // 结构体成员放置原则:按序存放,参考测试3,4
    
    // 测试1:原则1,原则2
    // 11 00 00 00 22 22 22 22  33 33 00 00 00 00 00 00
    // 44 44 44 44 44 44 44 44  55 55 55 55 00 00 00 00
    // sizeof(AA)==32
    struct AA{
        char a;            // 0x61fdd0    11
        int b;             // 0x61fdd4    22      
        short c;           // 0x61fdd8    33 
        double d;          // 0x61fde0    44
        float e;           // 0x61fde8    55
    };
    
    // 测试2:原则3
    // 11 00 00 00 22 22 22 22  33 33 00 00
    // sizeof(BB)==12
    struct BB{
        char a;            // 0x61fdd0    11
        int b;             // 0x61fdd4    22      
        short c;           // 0x61fdd8    33
    };
    
    // 测试3: 从小到大依次放成员
    // 11 00 22 22 33 33 33 33  44 44 44 44 00 00 00 00
    // 55 55 55 55 55 55 55 55
    // sizeof(AA1)==24
    struct AA1{
        char a;            // 0x61fdc0    11
        short b;           // 0x61fdc2    22 
        int c;             // 0x61fdc4    33      
        float d;           // 0x61fde8    44
        double e;          // 0x61fde0    55
    };
    
    // 测试4: 从大到小依次放成员
    // 11 11 11 11 11 11 11 11  22 22 22 22 33 33 33 33
    // 44 44 55 00 00 00 00 00
    // sizeof(AA2)==24
    struct AA2{
        double a;          // 0x61fde0    55   
        float b;           // 0x61fde8    44
        int c;             // 0x61fdc4    33
        short d;           // 0x61fdc2    22  
        char e;            // 0x61fdc0    11
    };
    
    void memory_dump(void *ptr, int len) {
        int i;
        for (i = 0; i < len; i++) {
            if (i % 8 == 0 && i != 0)
                printf(" ");
            if (i % 16 == 0 && i != 0)
                printf("
    ");
            printf("%02x ", *((uint8_t *)ptr + i));
        }
        printf("
    ");
    }
    
    void printMemoryInfo(struct AA2 structObj){
        memset(&structObj,0x00,sizeof(structObj));
        memset(&structObj.a,0x11,sizeof(structObj.a));
        memset(&structObj.b,0x22,sizeof(structObj.b));
        memset(&structObj.c,0x33,sizeof(structObj.c));
        memset(&structObj.d,0x44,sizeof(structObj.d));
        memset(&structObj.e,0x55,sizeof(structObj.e));
        
        memory_dump(&structObj,sizeof(structObj));
    
        cout<<"a:"<<&structObj<<endl;
        cout<<"b:"<<&structObj.b<<endl;
        cout<<"c:"<<&structObj.c<<endl;
        cout<<"d:"<<&structObj.d<<endl;
        cout<<"e:"<<&structObj.e<<endl;
        cout<<sizeof(structObj)<<endl;
    }
    
    void printMemoryInfo1(struct BB structObj){
        memset(&structObj,0x00,sizeof(structObj));
        memset(&structObj.a,0x11,sizeof(structObj.a));
        memset(&structObj.b,0x22,sizeof(structObj.b));
        memset(&structObj.c,0x33,sizeof(structObj.c));
    
        memory_dump(&structObj,sizeof(structObj));
    
        cout<<"a:"<<&structObj<<endl;
        cout<<"b:"<<&structObj.b<<endl;
        cout<<"c:"<<&structObj.c<<endl;
        cout<<sizeof(structObj)<<endl;
    }
    
    // 5 vector 对象
    // sizeof vectorObj=24, 因为有三个指针
    // iterator start          // 当前空间的头
    // iterator end            // 当前空间的尾
    // iterator end_of_storage // 空用空间的尾
    vector<int> vectorObj;
    
    // 6 list对象
    // sizeof listObj=24, 因为有2个指针+一个size_t
    // _List_node_base *_M_next;  // 前指针
    // _List_node_base *_M_prev;  // 后指针
    // std::size_t _M_size;       // 节点个数
    list<int> listObj;
    
    // 7 forwardlist 对象
    // sizeof forwardListObj= 8 : 仅有一个next指针
    forward_list<int> forwardListObj;
    
    // 8 deque 对象
    // sizeof deque = 80  :(4+4+2)*8=80
    // 2 
    // _Map_pointer _M_map;   指向map:记录元素存放的桶位置
    // size_t _M_map_size;    map的大小:桶的个数
    
    // ( 指向下面四个_M_cur,_M_first,_M_last,_M_node
    // iterator _M_start;     第一个节点的位置:
    // iterator _M_finish;    最后一个节点的下一个位置:
    // )
    
    // 4
    // _Elt_pointer _M_cur;
    // _Elt_pointer _M_first;
    // _Elt_pointer _M_last;
    // _Map_pointer _M_node;
    deque<int> dequeObj;
    
    
    // 9 stack 对象
    // sizeof stackObj = 80, 基于deque实现,因此是dequeue的大小
    stack<int> stackObj;
    
    // 10 queue 对象
    // sizeof queueObj = 80, 基于deque实现,因此是dequeue的大小
    queue<int> queueObj;
    
    // 11 rb_tree 对象
    // sizeof rbTreeObj = 48
    // _Rb_tree_color	_M_color;                   枚举bool值《-》需要对齐
    // _Base_ptr		_M_parent;                  指向父节点的指针
    // _Base_ptr		_M_left;                    指向左孩子的指针
    // _Base_ptr		_M_right;                   指向右孩子的指针
    // size_t		_M_node_count               节点数量
    // __gnu_cxx::__aligned_membuf<_Val> _M_storage 存放数据的指针
    _Rb_tree<int, int, int,std::less<int>> rbTreeObj;
    
    // 12 map 对象
    // sizeof mapObj = 48 map和set的底层数据结构就是红黑树,因此大小为48
    map<int,int> iMap;
    
    // 13 set 对象
    // sizeof msetObj = 48 map和set的底层数据结构就是红黑树,因此大小为48
    set<int> iSet;
    
    // 14 hashtable        <-这儿的分析还有待大佬修正,由于visiual studio 坏了,一时间分析看不到内存
    // size of hashTableObj=56
    // __bucket_type *_M_buckets = &_M_single_bucket;
    // size_type _M_bucket_count = 1;
    // __node_base _M_before_begin;-->*next,*cur,val空间指针
    // size_type _M_element_count = 0;
    // _RehashPolicy _M_rehash_policy;
    
    // 15 unorderd_map、unorderd_set 对象
    // sizeof uiMap = 56, 因为底层是依靠hashtable实现的
    unordered_map<int,int> uiMap;
    
    int main(){
        // class size
        emptyClass emptyObj;
        hasGeneralFuntionClass generalObj;
        hasVirtualFunctionClass virtualObj;
        cout<<sizeof(emptyObj)<<endl;
        cout<<sizeof(generalObj)<<endl;
        cout<<sizeof(virtualObj)<<endl;
    
        // base type size
        cout<<sizeof(char)<<endl;                // 1
        cout<<sizeof(short)<<endl;               // 2
        cout<<sizeof(int)<<endl;                 // 4
        cout<<sizeof(float)<<endl;               // 4
        cout<<sizeof(double)<<endl;              // 8
        cout<<"size_t:"<<sizeof(size_t)<<endl;   // 8
    
        // struct size
        struct AA2 structDoubleObj;
        struct BB structIntObj;
        printMemoryInfo(structDoubleObj);
        printMemoryInfo1(structIntObj);
    
        // vector size
        cout<<sizeof(vectorObj)<<endl;
    
        // list size
        cout<<sizeof(listObj)<<endl;
    
        // forward_list
        cout<<sizeof(forwardListObj)<<endl;
    
        // deque size
        cout<<sizeof(dequeObj)<<endl;
    
        // stack size
        cout<<sizeof(stackObj)<<endl;
    
        // queue size
        cout<<sizeof(queueObj)<<endl;
    
        // rb_tree size
        cout<<sizeof(rbTreeObj)<<endl;
        memory_dump(&rbTreeObj,sizeof(rbTreeObj));
    
        // map size
        cout<<sizeof(iMap)<<endl;
    
        // set size
        cout<<sizeof(iSet)<<endl;
    
        // hashtable size
    
        // unorderd_map size
        cout<<sizeof(uiMap)<<endl;
        return 0;
    }
    
  • 相关阅读:
    谷歌的 I/O 2019,究竟推出了什么新特性?
    Flutter交互实战-即刻App探索页下拉&拖拽效果
    5G到来,App的未来,是JavaScript,Flutter还是Native ?
    python爬虫-房天下-登录
    python爬虫-有道翻译-js加密破解
    虾米音乐爬虫
    Golang 读写文件
    Golang-使用md5对字符串进行加密
    Golang-使用mysql
    Golang 传递任意类型的切片
  • 原文地址:https://www.cnblogs.com/Alexkk/p/15036471.html
Copyright © 2011-2022 走看看