返回指针取消引用的c ++会导致分段错误

时间:2016-06-02 07:22:19

标签: c++ pointers

我有一个映射指针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;
}

4 个答案:

答案 0 :(得分:3)

m是一个未初始化的全局指针。编译器为其提供默认值nullptr。因此,您只需在取消引用时调用未定义的行为 - 您可能尝试在零地址处读取或写入内存,从而导致分段错误。

如何解决:

  • 定义一个std :: map对象并使m指向那里

    std::map<int, std::string> glob_map;
    std::map<int, std::string> *m = &glob_map;
    ... remaining of code unchanged
    
  • make 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();

答案 1 :(得分:2)

您根本没有初始化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;
}

答案 2 :(得分:0)

您只需创建并分配一个指向std::map的指针,而不是map本身。因此m指向无处,并且取消引用它是未定义的行为。

你可能想要像

这样的东西
 std::map<int, std::string> *m = new map<int, std::string>();

答案 3 :(得分:-1)

您所显示的代码没有问题(除了您从未初始化m之外)。

问题可能是代码中的其他地方。

最可能的问题是:

  • 在初始化m之前调用getMap
  • m被销毁后你致电getMap

使用像valgrind这样的东西来识别它是哪一个并获得有关该问题的更多信息。