c++面试常见问题:虚表指针存在于内存哪个分区

在 C++ 中,虚表指针(vptr)所在的内存分区与对象的存储位置相关,下面分不同情况进行介绍:

栈区

当对象是在栈上创建的局部对象时,虚表指针会随着对象一起被分配到栈区。栈区主要用于存储函数内部的局部变量和函数调用的上下文信息,其内存分配和释放由系统自动管理。当函数执行结束,栈上的对象会被自动销毁,虚表指针也随之消失。

示例代码

#include <iostream>

class Base {
public:
    virtual void func() {
        std::cout << "Base::func()" << std::endl;
    }
};

void test() {
    Base obj;  // 在栈上创建对象
    // obj 对象的虚表指针位于栈区
    obj.func();
}

int main() {
    test();
    return 0;
}

在上述代码中,test 函数内部的 Base 对象 obj 是在栈上创建的,该对象包含的虚表指针也会存储在栈区。

堆区

  如果对象是使用 new 运算符在堆上动态分配的,那么虚表指针会随着对象一起被分配到堆区。堆区用于动态内存分配,由程序员手动管理内存的分配和释放(使用 new 和 delete)。只要对象没有被显式地使用 delete 释放,它就会一直存在于堆区,虚表指针也会一直存在。

示例代码

#include <iostream>

class Base {
public:
    virtual void func() {
        std::cout << "Base::func()" << std::endl;
    }
};

int main() {
    Base* ptr = new Base();  // 在堆上创建对象
    // ptr 指向的对象的虚表指针位于堆区
    ptr->func();
    delete ptr;  // 释放堆上的对象
    return 0;
}

 在这个例子中,Base 对象是通过 new 运算符在堆上创建的,其虚表指针也会存储在堆区,直到使用 delete 释放该对象。

全局 / 静态存储区

  当对象是全局对象或者静态对象时,虚表指针会存储在全局 / 静态存储区。全局对象在程序启动时就被创建,直到程序结束才被销毁;静态对象在第一次使用时被创建,并且在程序的整个生命周期内都存在。

示例代码

#include <iostream>

class Base {
public:
    virtual void func() {
        std::cout << "Base::func()" << std::endl;
    }
};

Base globalObj;  // 全局对象,虚表指针位于全局/静态存储区

void test() {
    static Base staticObj;  // 静态对象,虚表指针位于全局/静态存储区
    staticObj.func();
}

int main() {
    globalObj.func();
    test();
    return 0;
}

在上述代码中,globalObj 是全局对象,staticObj 是静态对象,它们的虚表指针都存储在全局 / 静态存储区。

虚表本身的存储位置

虚表(vtable)通常存储在只读数据段(RODATA),这是因为虚表中的内容在程序运行期间是固定不变的,包含了类的虚函数的地址等信息,将其放在只读数据段可以保证数据的安全性和共享性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值