2015-07-31 4 views
-4

Когда я пытаюсь добавить указатель на указатель std :: list, я получаю segfault. Зачем?Почему это вызывает segfault в C++?

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); 
} 
+2

Вы не инициализировали 'pList'. Лучше не указатели. – juanchopanza

+2

Вы указываете ** указатель на список ** и не инициализируете указатель и не выделяете что-либо для указателя, на который указывает. –

+7

Стоп со всеми указателями. –

ответ

2

Это вызывает Segfault потому 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. 

Если вы включите предупреждение компилятора на (до) компилятор предупредит вас это проблема. Вы должны действительно сказать своему компилятору, чтобы рассматривать все предупреждения как ошибки.

Как вы его решаете.

Вам следует создать список.

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. 
}