C++中类型、数组、结构体、类所占字节数

作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

前言

在考虑内存管理之前,我们要先知道资源所占的内存大小。博主在这里整理了一些基础元素所占的字节大小,防止长时间不接触而遗忘掉。

基础类型

cout << sizeof(char) << endl;       //1
cout << sizeof(short) << endl;      //2
cout << sizeof(int) << endl;        //4
cout << sizeof(long) << endl;       //4
cout << sizeof(long long) << endl;  //8
cout << sizeof(char*) << endl;      //32位4个字节,64位8个字节
cout << sizeof(float) << endl;      //4
cout << sizeof(double) << endl;     //8

这里有小伙伴经常会问一个问题,为什么指针在32位的系统占4个字节,而在64位系统会占8个字节呢?
我们知道cpu是无法直接在硬盘上读取数据的,而是通过内存读取。cpu通过地址总线、数据总线、控制总线三条线对内存中的数据进行传输和操作。

具体流程:
  1、cpu通过地址总线,找到该条数据;
  2、通过控制总线得知该操作是读操作还是写操作;
  3、通过数据总线将该数据读取到cpu或者从cpu写到内存中;

我们平时所说的计算机是64位、32位、16位,指的是计算机CPU中通用寄存器一次性处理、传输、暂时存储的信息的最大长度。简单的说32位的操作系统就是指:地址总线是32位的系统。那么,也就是说操作系统的位数决定了指针变量所占的字节数。

数组

const char *str1 = "my program";
char str2[] = "my program";
//char str3[10] = "my program";	//error C2117: 'my program' : array bounds overflow
char str4[100] = "my program";
int str5[100];
char str6[] = "abc";
char str7[] = "a\n";
char *str8 = (char *)malloc(100);
void *str9 = (void *)malloc(100);

cout << sizeof(str1) << endl;	//4 str1是指向字符串常量的字符指针,sizeof获得的是一个指针所占的空间
cout << sizeof(str2) << endl;	//11
cout << sizeof(str4) << endl; 	//100
cout << strlen(str1) << endl;	//10
cout << strlen(str2) << endl;	//10
cout << strlen(str4) << endl;	//10
cout << sizeof(str5) << endl; 	//400
cout << sizeof(str6) << endl; 	//4
cout << sizeof(str7) << endl; 	//3
cout << sizeof(str8) << endl; 	//4
cout << sizeof(str9) << endl; 	//4

结构体

struct{
    short a;	//2
    double b	//8
    char c	//1
}A;

struct{
    short a;	//2
    long b	//4
}B;

struct{
    short a;	//2
    int b	//4
    double c	//8
}C;

struct{
    double a;	//8
    short b	//2
}D;

cout << sizeof(A) << endl;      //24
cout << sizeof(B) << endl;      //8
cout << sizeof(C) << endl;      //16
cout << sizeof(D) << endl;      //16

结构体字节对齐的规则如下:

  1. 结构体中元素按照定义顺序依次置于内存中,但并不是紧密排列。从结构体首地址开始依次将元素放入内存时,元素会被放置在其自身对齐大小的整数倍地址上;
  2. 如果结构体大小不是所有元素中最大对齐大小的整数倍,则结构体对齐到最大元素对齐大小的整数倍,填充空间放置到结构体末尾;
  3. 基本数据类型的对齐大小为其自身的大小,结构体数据类型的对齐大小为其元素中最大对齐大小元素的对齐大小;

例1:
class A {};

class B {
    int a;
    char b;
};

class C: public A {};

class D: public virtual B {};

class E: public A, public B {};

cout << sizeof(A) << endl;      //1
cout << sizeof(B) << endl;      //8
cout << sizeof(C) << endl;      //1
cout << sizeof(D) << endl;      //12
cout << sizeof(E) << endl;      //8
例2:
class A {
public:
    int a;
    static int b;
    A();
    ~A();
};

class B {
public:
    int a;
    char c;
    B();
    ~B();
    int add();
    static int test();
};

class C {
public:
    float a;
    char c;
    C();
    virtual ~C();
    virtual void test();
};

class D {
public:
    float a;
    char b;
    double c;
    int d;
    const double e;
    D();
    ~D();
};

cout << sizeof(A) << endl;     //4
cout << sizeof(B) << endl;     //8
cout << sizeof(C) << endl;     //12
cout << sizeof(D) << endl;     //32

总结一下计算一个类对象大小的规律:

  1. 空类、单一继承的空类、多重继承的空类所占空间大小为:1个字节;
  2. 一个类中,虚函数本身、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间的;
  3. 当类中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针vPtr指向虚函数表VTable;
  4. 虚承继的情况:由于涉及到虚基表,会增加一个vbPtr指针指向虚基表vbTable;
  5. 在考虑以上内容所占空间的大小时,还要注意编译器插入的字节补齐;
发布了61 篇原创文章 · 获赞 218 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34139994/article/details/105088157
今日推荐