【C++】類型截斷引起的Bug

類型截斷引起的Bug

背景

最近遇到了一個Bug,由於崩潰堆棧定位到的是一個第三方的so中,查了許久。最終,定位到了出問題的部分。

現象原因:
Model層傳給UI層,一個用於描畫的Buffer。在使用前,該Buffer被異常釋放。導致UI層再調用第三方庫,創建紋理時崩潰。

根本原因:
C++類型截斷導致

類型截斷

  • 下面的代碼展示了類型截斷的發生,以及導致Bug發生的現象
// 父類
class Parent
{
	public:
		void* buffer;
}

// 子類
class Child : public Parent
{
	public:
		std::shared_ptr<BitMap> buf;
}

// 由於編譯限制,接口層禁止使用C++11。
// 所以在Model層,使用智能指針保存buf
// 爲UI層提供原始指針 buffer
std::map<Parent> m_bufferMap;
void saveBitmap(BitMap* bitmap)
{
	Child node;
	node.buf.reset(bitmap);
	node.buffer = buf.get();
	
	// 將子類賦值給父類類型
	// 發生類型截斷
	// 導致子類部分的智能指針被釋放
	// 給外部用的buffer,此時是一個非法地址了
	m_bufferMap.push_back(node)
}
  • 上面的例子鍾,將子類對象賦值給父類類型的對象時,會發生類型截斷。子類中多餘的部分,將會被拋棄。
  • 那麼如何防止,這種現象?
// 1. 使用指針類型
Parent* p = new Child()

// 2. 對於棧上申請的對象,使用正確的類型保存
std::map<Child> m_map;
Child Node;
map.push_back(Node);

總結

  • 問題的原因比較簡單,就是C++的一個基本概念。但是該原因導致的問題,以及定位問題的調查過程,還是比較久的。因此,一定要對語言的基本概念會深刻的瞭解,特別是底層語言,否則很容易自己挖坑。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章