为什么这会在c++中导致段错误

Why does this cause a segfault in C++?

本文关键字:段错误 错误 c++ 为什么      更新时间:2023-10-16

当我尝试将对象指针添加到std::列表指针时,我得到一个段错误。为什么?

object.h

#ifndef DELETEME_H
#define DELETEME_H
class Object
{
public:
  Object(): yes(0) {};
  int yes;
};
#endif

object.cpp

#include <list>
#include "deleteme.h"
int main()
{
  std::list<Object*> *pList;
  Object *pObject;
  pObject = new Object();
  pList->push_front(pObject);
}

pList未初始化导致段故障

  std::list<Object*> *pList;    // You declared it but you have not said what
                                // value lives here.

所以当你尝试使用它时:

  pList->push_front(pObject);   // This is undefined behavior.

如果你把编译器的警告打开(up),编译器会警告你这是一个问题。你应该告诉编译器把所有的警告都当作错误来处理。

你是怎么解决的?

你应该创建一个列表。

std::list<Object*> *pList  = new std::list<Object*>;

但是创建它作为一个指针是一个坏主意(不是一个非常坏的主意)。你刚刚打开了一个你不想处理的漏洞。你不应该(几乎不读(或者干脆不读))动态地创建内存。这会导致异常和泄漏等各种问题。在你理解所有权语义之前,坚持使用对象。

std::list<Object> pList;
pList.push_back(Object());

在注释中,您担心从函数返回它。

std::list<Object>  getList()
{
   std::list<Object>   result;
   result.push_back(Object());
   result.push_back(Object());
   return result;
}
int main()
{
     // Technically this copies the list out of the function
     // when the return is called (so your object and the list)
     // must be copyable.
     std::list<Object>   data = getList();
     // But in reality it will not be copied.
     // Because the copiler will invoke NRVO and build it in place
     // at the destination. If you put print statements in your objects
     // constructor/destructor etc.. you can try and spot the copies.
     // Turn on optimizations and any copies that did exist will be
     // removed.
}