[英]What is the default constructor for C++ pointer?
我有這樣的代碼:
class MapIndex
{
private:
typedef std::map<std::string, MapIndex*> Container;
Container mapM;
public:
void add(std::list<std::string>& values)
{
if (values.empty()) // sanity check
return;
std::string s(*(values.begin()));
values.erase(values.begin());
if (values.empty())
return;
MapIndex *&mi = mapM[s]; // <- question about this line
if (!mi)
mi = new MapIndex();
mi->add(values);
}
}
我主要關心的是,如果將新項目添加到地圖中,mapM[s] 表達式是否會返回對 NULL 指針的引用?
SGI 文檔是這樣說的: data_type& operator[](const key_type& k) 返回對與特定鍵關聯的對象的引用。 如果地圖尚未包含此類對象,operator[] 將插入默認對象 data_type()。
所以,我的問題是插入默認對象 data_type()是否會創建一個 NULL 指針,或者它可能會創建一個指向內存中某處的無效指針?
它會創建一個NULL
(0) 指針,無論如何這是一個無效的指針:)
是的,它應該是一個零 (NULL) 指針,因為當 stl 容器沒有顯式存儲對象時,它們將默認初始化對象(即在您執行操作時訪問映射中不存在的鍵或將向量調整為更大的大小)。
C++ 標准,8.5 第 5 段指出:
默認初始化 T 類型的對象意味着:
- 如果 T 是非 POD 類類型(子句類),則調用 T 的默認構造函數(如果 T 沒有可訪問的默認構造函數,則初始化是格式錯誤的)
- 如果 T 是數組類型,則每個元素都默認初始化
- 否則,對象的存儲是零初始化的。
您還應該注意,默認初始化與簡單地省略構造函數不同。 當您省略構造函數並簡單地聲明一個簡單類型時,您將獲得一個不確定的值。
int a; // not default constructed, will have random data
int b = int(); // will be initialised to zero
更新:我完成了我的程序,我問的那一行有時會導致它崩潰,但在稍后階段。 問題是我正在創建一個新對象而不更改存儲在 std::map 中的指針。 真正需要的是引用或指向該指針的指針。
MapIndex *mi = mapM[s]; // <- question about this line
if (!mi)
mi = new MapIndex();
mi->add(values);
應改為:
MapIndex* &mi = mapM[s]; // <- question about this line
if (!mi)
mi = new MapIndex();
mi->add(values);
我很驚訝沒有人注意到這一點。
表達式data_type()
值初始化一個對象。 對於具有默認構造函數的類類型,它會被調用; 如果它不存在(或被默認),例如指針,則對象被零初始化。
所以是的,你可以依靠你的地圖創建一個NULL
指針。
不確定崩潰,但肯定有內存泄漏,因為這個語句:
if (!mi)
mi = new MapIndex();
始終返回 true,因為指針mi
不是對mapM
為s
的特定值所持mapM
內容的引用。
我也會避免使用常規指針並使用boost::shared_ptr
或其他一些在銷毀時釋放內存的指針。 這允許您調用mapM.clear()
或erase()
,它們應該調用存儲在映射中的鍵和值的析構函數。 好吧,如果值是 POD,例如您的指針,那么除非手動刪除,否則不會為此調用析構函數,而遍歷整個映射將導致內存泄漏。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.