C++ 内存划分与虚函数表在内存中的位置

一直都不清楚C++的内存具体是怎样划分的,只知道大致有堆区、栈区、全局静态区、常量区等划分。如果没记错的话,好像还有一个代码区。
现在的问题是,C++里的虚函数是借助虚函数表实现的,含有虚函数的类的对象中有一个指向虚函数的指针(通常是对象前4个字节(32位))。
那么,虚函数表是保存在内存中的哪个部分中呢?
在网上查了一些资料也没搞明白,只好自己动手研究。

首先进行简单的分析,虚函数表应该是在编译期就已经决定了的,所以不可能在堆区与栈区。虚函数也不属于代码,所以推测在静态区或常量区。

有一个简单的测试思路,写一个简单的C++程序,把各个区段的地址和虚函数表地址都输出出来,通过地址的位置来判断。

撸出代码如下:

#include <cstdio>
#include <cstdlib>

using namespace std;

typedef void (*FP)();
FP fp;

void fun() {
    int t;
    printf("〇〇〇栈区:0x%08X\n", (unsigned)&t);
}

class Base {
    public:
    virtual void gao() {
        printf("Base\n");
    }
    virtual ~Base() {}
};

class Derived : Base {
public:
    virtual void gao() {
        printf("Derived\n");
    }
    virtual void dio() {
        printf("URYYYYYY\n");
    }
    virtual ~Derived() {}

};

Base b;
Derived d;

int glob = 0;
int glob2 = 0;

const int cons = 0;

int main()
{
    int stk = 0;
    int stk2 = 0;
    const char *p = "123456";
    const char *p2 = "3333";
    unsigned table = *((unsigned*)&b);
    unsigned table2 = *((unsigned*)&d);

    printf("sizeof(void*) %d\n", sizeof(void*));

    char *heap =(char *) malloc(100);
    char *heap2 = new char[100];

    printf("〇〇〇栈区:0x%08X\n", (unsigned)&stk);
    printf("〇〇〇栈区:0x%08X\n", (unsigned)&stk2);
    fun();

    fp = fun;
    printf("〇〇函数区:0x%08X\n", (unsigned)&(*fp));

    printf("〇〇常量区:0x%08X\n", (unsigned)&(*p));
    printf("〇〇常量区:0x%08X\n", (unsigned)&(*p2));
    printf("〇〇常量区:0x%08X\n", (unsigned)&cons);

    printf("〇虚函数表:0x%08X\n", table);
    printf("〇虚函数表:0x%08X\n", table2);

    printf("全局静态区:0x%08X\n", (unsigned)&glob);
    printf("全局静态区:0x%08X\n", (unsigned)&glob2);

    printf("〇〇〇堆区:0x%08X\n", (unsigned)&(*heap));
    printf("〇〇〇堆区:0x%08X\n", (unsigned)&(*heap2));

    return 0;
}

运行后输出结果:

sizeof(void*) 4
〇〇〇栈区:0x0029FEE4
〇〇〇栈区:0x0029FEE0
〇〇〇栈区:0x0029FE7C
〇〇函数区:0x00401334
〇〇常量区:0x0040E04E
〇〇常量区:0x0040E055
〇〇常量区:0x0040E0D0
〇虚函数表:0x0040FCD0
〇虚函数表:0x0040FCE8
全局静态区:0x00411014
全局静态区:0x00411018
〇〇〇堆区:0x00830DF0
〇〇〇堆区:0x00830E60

推测出内存划分为以下几个部分:

  1. 栈区
  2. 函数区(函数区是代码区吗?)
  3. 常量区
  4. 虚函数表(虚函数表属于哪个区段?)
  5. 全局静态区
  6. 堆区

因此,虚函数表介于常量区和全局区之间。虚函数表似乎可以单独作为一个分区,或许内存划分方式并不像想象中那么严格。

以后查到资料再回来添加。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值