簡體   English   中英

c ++返回指針的取消引用會導致分段錯誤

[英]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
  • m被銷毀后,您可以調用getMap

使用valgrind之類的東西來確定它是哪一個,並獲取有關該問題的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM