«

C++虚函数表存储位置在哪

时间:2024-7-14 15:41     作者:韩俊     分类: Java


这篇文章主要介绍“C++虚函数表存储位置在哪”,在日常操作中,相信很多人在C++虚函数表存储位置在哪问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++虚函数表存储位置在哪”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

前言

先说结论:虚函数表存储在只读数据段

.rodata
)、虚函数存储在代码段(
.text
)、虚表指针的存储的位置与对象存储的位置相同,可能在栈、也可能在堆或数据段等。

反汇编

环境:

gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04)

验证代码:

#include <iostream>
using namespace std;

class Q {
public:
    virtual void Test() {
        cout << "Test" << endl;
    }
};

class Qgw : public Q {
public:
    virtual void Test() {
        cout << "Test Position" << endl;
    }
};

int main() {
    Q* q = new Qgw;
    q->Test();
    return 0;
}

并不采用打印地址的方式,因为打印出的地址与反汇编得到的地址不同,无法直接得出结果。

首先编译代码:

g++ -o test test.cc -O0 -m32
,以 32 位方式编译。

然后将符号表输出到文件:

objdump -tC test > test.txt

打开 test.txt 可以找到以下内容:

000012fc  w    F .text            00000044      Qgw::Test()
0000201c  w    O .rodata        00000005      typeinfo name for Qgw
00003ea8  w    O .data.rel.ro    0000000c      typeinfo for Qgw
00003e90  w    O .data.rel.ro    0000000c      vtable for Qgw

第一行比较清晰,说明

Qgw::Test()
存储在
.text
段,也就说明虚函数和普通函数一样,都存储在代码段。

下面几行又是什么东西呢?

根据《深度探索 C++ 对象模型》的 C++ 对象模型可知,typeinfo 是存储在虚函数表中,用来获取对象类型信息的。最下面的

.data.rel.ro
是只读数据段的重定位段,在链接时重定位。由此,可以推出虚函数表是存储在只读数据段的。

相近地址

也可以采用打印地址的方式,与已知的一些段地址比较,看虚函数表地址和哪个段地址更接近。

环境:

gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04)

验证代码:

#include <iostream>
using namespace std;

class Qgw {
public:
    virtual void Test() {
        cout << "Test Position" << endl;
    }
};

void Func() {
    cout << "func" << endl;
}

int n = 10;

int main() {
    Qgw* q = new Qgw;
    q->Test();

    const char* arr = "qgw";
    cout << "text:     " << (void*)Func << endl;
    cout << ".rodata:  " << (void*)arr << endl;
    cout << "虚函数表: "  << *(void**)q << endl;
    cout << ".data:    " << &n << endl;
    return 0;
}

函数的地址在上文已经验证了,全局变量和常量字符串的位置,《深入理解计算机系统(第三版)》中说明如下:

.rodata
:只读数据 比如 printf 语句中的格式串(
%d
.data
已初始化的全局和静态 C 变量

它们的布局如下图:

编译运行上述代码,得到以下结果:

可以看到虚函数表的位置在数据段和只读数据段位置之间,我们是无法手动修改虚函数表的,因此存储在只读数据段是比较合理的。

标签: java

热门推荐