C++中内存对齐与对象指针指向空指针的对象大小

    技术2025-02-24  39

    C++中内存对齐与对象指针指向空指针的对象大小

    首前看一段程序,判断一下其输出结果是什么:

    #include <iostream> #include <vector> #include <algorithm> #include <bitset> using namespace std; class A{ int a; int b; double c; char name; char name2; public: virtual void myFun(){ cout<<"test"<<endl; } void myFun2(){ cout<<"fun2"<<endl; } }; int main(){ A *a = NULL; cout<< sizeof(a)<<" "<< sizeof(*a)<<endl; a->myFun(); a->myFun2(); return 0; }

    在Windows10 64位系统下,使用MInGW(gcc)作为编译器的情况下, 输出: 当执行a的myFun()函数时程序出错退出.

    将普通函数的调用注释掉:

    int main(){ A *a = NULL; cout<< sizeof(a)<<" "<< sizeof(*a)<<endl; // a->myFun(); a->myFun2(); return 0; }

    输出: 可以看到程序是正常结束的。 分析: 因为对象a的虚函数表示空的,所以调用虚函数时程序退出;而在调用普通函数时,实际调用形式是:A::myFun2(this),this指向调用对象,这里的this对象是一个空对象,在进行与成员变量无关的操作的时候是可以正常进行的。 sizeof(a)得到的是一个指针的大小,为8字节;sizeof(*a)得到了一个对象的大小,但是这里要遵循字节对齐的规则,虚函数表指针:8,成员变量:4+4+8+1+1=18,总大小为8+18=26,但是大小应为最大成员变量的整数倍,所以为:32


    下面再来看一下一个空对象的大小:

    #include <iostream> #include <vector> #include <algorithm> #include <bitset> using namespace std; class A{ // int a; // int b; // double c; // char name; // char name2; public: // virtual void myFun(){ // cout<<"test"<<endl; // } void myFun2(){ cout<<"fun2"<<endl; } }; int main(){ A *a = NULL; cout<< sizeof(a)<<" "<< sizeof(*a)<<endl; // a->myFun(); a->myFun2(); return 0; }

    输出结果为: “To ensure that the addresses of two different objects will be different.”所以即使一个类不含任何成员,也要有一个字节来标示其身份。

    参考: C++空指针能调用类成员函数吗? C++ 中空类对象为什么占一个字节?

    Processed: 0.011, SQL: 9