[英]c++ returning dereference of a pointer causes Segmentation fault
我有一個映射指針m
,它不是函數getMap
的局部變量, getMap
返回指針m
的取消引用,當我運行下面的代碼時,遇到了Segmentation fault (core dumped)
,為什么返回指針的取消引用會導致分段故障。
std::map<int, std::string> *m;
const std::map<int, std::string>& getMap(){
m->insert(std::make_pair<int, std::string>(0, "hi"));
return *m;
}
int main(){
const std::map<int, std::string>& m = getMap();
std::cout << "length: " << m.size() << std::endl;
}
m
是未初始化的全局指針。 編譯器為其提供默認值nullptr
。 因此,在取消引用時,您只是調用未定義的行為-您可能試圖在零地址處讀取或寫入內存,這會導致分段錯誤。
怎么修:
定義一個std :: map對象並使m
指向那里
std::map<int, std::string> glob_map; std::map<int, std::string> *m = &glob_map; ... remaining of code unchanged
使GetMap
返回臨時
const std::map<int, std::string> getMap(){ std::map<int, std::string> localmap localmap.insert(std::make_pair<int, std::string>(0, "hi")); return m; } int main(){ const std::map<int, std::string>& m = getMap(); std::cout << "length: " << m.size() << std::endl; }
這是一種相當高級的方法,因為您使用了這樣一個事實,即當臨時變量直接影響到引用時,它的壽命會延長。 通常的方法是將臨時副本復制到普通對象(並讓優化編譯器消除不必要的副本):
const std::map<int, std::string> m = getMap();
您根本沒有初始化m
,而對其取消引用是UB。 您需要對其進行new
(和delete
)操作。
如果您不必使用原始指針,則不要使用。
std::map<int, std::string> m;
const std::map<int, std::string>& getMap(){
m.insert(std::make_pair<int, std::string>(0, "hi"));
return m;
}
您只需創建並分配一個指向std::map
指針,而不分配給map
本身。 因此, m
指向無處,而取消引用它是未定義的行為。
您可能想要類似
std::map<int, std::string> *m = new map<int, std::string>();
您顯示的代碼沒有問題(除了您從未初始化m之外)。
問題可能出在代碼的其他地方。
最可能出現的問題是:
getMap
在初始化m之前調用getMap
。 getMap
。 使用valgrind之類的東西來確定它是哪一個,並獲取有關該問題的更多信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.