当前位置: 首页 > article >正文

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),这是因为虚表中的内容在程序运行期间是固定不变的,包含了类的虚函数的地址等信息,将其放在只读数据段可以保证数据的安全性和共享性。


http://www.kler.cn/a/572402.html

相关文章:

  • Node.js学习分享(上)
  • python爬虫数据库概述
  • 【Java】IO流
  • Linux·数据库INSERT优化
  • PyTorch 与 NVIDIA GPU 的适配版本及安装
  • NO.23十六届蓝桥杯备战|二维数组|创建|初始化|遍历|memset(C++)
  • Kconfig与CMake初步模块化工程3
  • 刷题日记——部分二分算法题目分享
  • 我如何从 Java 和 Python 转向 Golang 的脚本和 GUI 工具开发
  • ThreadLocal解析
  • CTF 中的 XSS 攻击:原理、技巧与实战案例
  • 【Web前端开发】---HTML标签及标签属性
  • 【练习】【链表】力扣热题100 206. 反转链表
  • 将 SSH 密钥添加到 macOS 的钥匙串中
  • 【GIS】算法原理:点、线、矩形的空间关系
  • 准确--Centos最小化安装通过命令去修改ip和dns
  • docker学习笔记(1)从安装docker到使用Portainer部署容器
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_cycle 函数 - 详解(11)
  • 【RandLA-Net】基于自建数据训练大场景语义分割网络RandLA-Net
  • 输电线路杆塔倾斜智能监测:守护电网安全的智慧之眼