溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++虛函數(shù)表存儲位置在哪

發(fā)布時間:2023-04-04 10:39:01 來源:億速云 閱讀:109 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹“C++虛函數(shù)表存儲位置在哪”,在日常操作中,相信很多人在C++虛函數(shù)表存儲位置在哪問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C++虛函數(shù)表存儲位置在哪”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

前言

先說結論:虛函數(shù)表存儲在只讀數(shù)據(jù)段.rodata)、虛函數(shù)存儲在代碼段(.text)、虛表指針的存儲的位置與對象存儲的位置相同,可能在棧、也可能在堆或數(shù)據(jù)段等。

反匯編

環(huán)境: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 可以找到以下內(nèi)容:

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 段,也就說明虛函數(shù)和普通函數(shù)一樣,都存儲在代碼段。

下面幾行又是什么東西呢?

根據(jù)《深度探索 C++ 對象模型》的 C++ 對象模型可知,typeinfo 是存儲在虛函數(shù)表中,用來獲取對象類型信息的。最下面的 .data.rel.ro 是只讀數(shù)據(jù)段的重定位段,在鏈接時重定位。由此,可以推出虛函數(shù)表是存儲在只讀數(shù)據(jù)段的。

C++虛函數(shù)表存儲位置在哪

相近地址

也可以采用打印地址的方式,與已知的一些段地址比較,看虛函數(shù)表地址和哪個段地址更接近。

環(huán)境: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 << "虛函數(shù)表: "  << *(void**)q << endl;
    cout << ".data:    " << &n << endl;
    return 0;
}

函數(shù)的地址在上文已經(jīng)驗證了,全局變量和常量字符串的位置,《深入理解計算機系統(tǒng)(第三版)》中說明如下:

.rodata:只讀數(shù)據(jù) 比如 printf 語句中的格式串(%d\n.data已初始化的全局和靜態(tài) C 變量

它們的布局如下圖:

C++虛函數(shù)表存儲位置在哪

編譯運行上述代碼,得到以下結果:

C++虛函數(shù)表存儲位置在哪

可以看到虛函數(shù)表的位置在數(shù)據(jù)段和只讀數(shù)據(jù)段位置之間,我們是無法手動修改虛函數(shù)表的,因此存儲在只讀數(shù)據(jù)段是比較合理的。

到此,關于“C++虛函數(shù)表存儲位置在哪”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

c++
AI