BUG memset引起的虛表異常

2021-08-21 21:11:01 字數 1167 閱讀 7585

先上**和結論:

class a;

int main()

a* pa = malloc(sizeof(a));

memset(pa,0,sizeof(a));

............

printf("hello world!");

}

大致偽**可以這麼寫了。

這裡看,就是使用了c的記憶體申請方式來初始化了乙個c++的類a的例項。這樣的做法,現在可能不常見,但是在比較老舊的框架或者**中依然存在。然後筆者經歷了乙個因為這種方式導致的詭異bug。

我們先討論一下,照c++的模式來思考,這裡可能存在的問題。

1,首先看sizeof(a)是否可能為0?

不可能,因為c++標準制定了,當a即使沒有任何成員變數時,sizeof(a)==1。否則sizeof(a)==0的話會導致無成員變數的類無法申請記憶體(因為成員函式不佔記憶體,至於成員函式和成員變數佔據記憶體的差異,這裡簡單說就是,成員函式不佔據任何類成員空間,因為他們所處的域不同,成員函式處於**段,而成員變數一般處於堆疊資料段)。所以即使是乙個有1000個成員方法沒有任何成員變數的類,他的size依然是1。

2,照1的結論來看,假設對於類,僅有類成員變數佔據空間的情況下,這裡應該是不存在問題的。**與資料分離,資料又被格式化為0。看上去很ok。但是實際上c++還有另外一種佔據類記憶體空間的物件,舉個例,比如虛表指標。

虛表:

這個不知道被面試題考過多少次,現在還在考)

這三篇文章看完看懂的話,就會理解上面這個**在某些情況下,就會出現問題。

在類存在虛函式的情況下,類會有一張虛表(除非你atl_no_vtable,)這樣,在c的初始化模式下,會將虛表的頭指標指向0位址,這樣就會造成非法指標訪問。因為虛函式是根據虛表頭進行索引找到虛函式入口位址,一旦虛表頭置0,那就是0是第乙個虛函式入口位址,發生虛函式訪問或者多型,立馬崩。

筆者在對應的出錯地看到了乙個 : 有效指標->有效方法的訪問模式,然後經過debug除錯查詢找到這個bug,中間涉及c++的記憶體模型,還有c++初始化和c模式的malloc初始化方式的區別,除了new之外,虛表還有其他很多因素都是malloc無法替代的。

warning!

分庫分表引起的問題

1 按照新舊分片規則,對新舊資料庫進行雙寫。2 將雙寫前按照舊分片規則寫入的歷史資料,根據新分片規則遷移寫入新的資料庫。3 將按照舊的分片規則查詢改為按照新分片規則查詢 4 將雙寫資料庫邏輯從 中下線,只按照新的分片規則寫入資料。5 刪除按照舊分片規則寫入的歷史資料。常見的解決方式 1 在多個分片表...

對虛函式 虛表的認識

虛函式 實現多型的機制,多型就是用父型別的指標指向其子類的例項,然後通過父類的指標呼叫實際子類的成員函式。讓父類的指標有 多種形態 一種泛型技術。關鍵字 virtual 虛函式表 此表中,主要是乙個類的虛函式的位址表,這張表解決了繼承 覆蓋的問題,保證其內容真實反映實際的情況。在c 標準規格說明書中...

C 虛表的原理

base b fun pfun null invoke the first virtual function pfun fun int int b pfun 實際執行經果如下 windows xp vs2003,linux 2.6.22 gcc 4.1.3 base f 通過這個示例,我們可以看到,...