逆向程序分析:C++的一个空类,为什么在内存中占1字节

Posted CodeBowl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆向程序分析:C++的一个空类,为什么在内存中占1字节相关的知识,希望对你有一定的参考价值。

普通的空类

空类的定义

空类就是没有任何数据成员的类。

空类的内存大小

按道理讲,没有数据成员,就不会占用内存,那么空类的大小就为0。
但是真实场景下,即便是空类在内存中,也占一个字节。

#include <iostream>
class CPeople
{

};

int main()
{
    std::cout << "sizeof(CPeople): " << sizeof(CPeople) << std::endl;
    CPeople *v1;
    return 0;
}

输出结果为:

sizeof(CPeople): 1

为了对比,我们建一个新类,里面增加一个数据成员。


#include <iostream>
class A
{

};

class B
{
    int i;
};

int main()
{
    std::cout << "sizeof(A): " << sizeof(A) << std::endl;
    std::cout << "sizeof(B): " << sizeof(B) << std::endl;

    return 0;
}


输出结果为:

sizeof(A): 1
sizeof(B): 4

为什么呢?

从其他地方看到的解释:

C++标准指出,
不允许一个对象(当然包括类对象)的大小为0,不同的对象不能具有相同的地址。
这是由于:
new需要分配不同的内存地址,不能分配内存大小为0的空间
避免除以 sizeof(T)时得到除以0错误 故使用一个字节来区分空类。

带有虚函数的空类

虚类空类在内存中的大小

给空类A加一个虚成员函数,那么这个类也变成了虚类。

#include <iostream>
class A
{
public:
    virtual int a() {
        
    }
};

class B
{
public:
    virtual int b() { }
    int i;
};

int main()
{
    
    std::cout << "sizeof(A): " << sizeof(A) << std::endl;
    std::cout << "sizeof(B): " << sizeof(B) << std::endl;

    return 0;
}


输出结果:

sizeof(A): 4
sizeof(B): 8

为什么?

因为,虚类中有一个虚表存放着虚函数的地址,虚类对象调用虚函数的时候,是通过虚表指针去寻址的,所以内存中存放着虚表指针,在32位下,占4字节。

A::A:
00A716E0 55                   push        ebp  
00A716E1 8B EC                mov         ebp,esp  
00A716E3 81 EC CC 00 00 00    sub         esp,0CCh  
00A716E9 53                   push        ebx  
00A716EA 56                   push        esi  
00A716EB 57                   push        edi  
00A716EC 51                   push        ecx  
00A716ED 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
00A716F3 B9 33 00 00 00       mov         ecx,33h  
00A716F8 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00A716FD F3 AB                rep stos    dword ptr es:[edi]  
00A716FF 59                   pop         ecx  
00A71700 89 4D F8             mov         dword ptr [this],ecx  
00A71703 8B 45 F8             mov         eax,dword ptr [this]  
00A71706 C7 00 34 6B A7 00    mov         dword ptr [eax],offset A::`vftable' (0A76B34h)  
00A7170C 8B 45 F8             mov         eax,dword ptr [this]  
00A7170F 5F                   pop         edi  
00A71710 5E                   pop         esi  
00A71711 5B                   pop         ebx  
00A71712 8B E5                mov         esp,ebp  
00A71714 5D                   pop         ebp  
00A71715 C3                   ret  

以上是关于逆向程序分析:C++的一个空类,为什么在内存中占1字节的主要内容,如果未能解决你的问题,请参考以下文章

C++类对象所占的内存空间

Windows 逆向CheatEngine 工具 ( 汉化版 CE 工具推荐 | 编写简单 C++ 程序 | C++ 程序执行分析 | 使用 CE 修改上述 C++ 程序 )

C++语法小记---经典问题之一(一个空类包含什么)

C++程序正向编译逆向反编译

C++程序正向编译Ghidra逆向反编译

c++逆向 vector