2013-02-20 2 views
0

У меня есть структура, которая содержит std :: list. В моем коде я пытаюсь перебрать этот список, но получаю некоторые нечетные результаты.std :: list.begin(), дающий нулевой указатель

struct my_struct_t { 
    std::list<int> my_list; 
    //More fields 
}; 

Это моя структура, как определено в моем файле заголовка.

И некоторые примеры кода в файле, который включает в себя этот заголовок будет:

std::list<int>::iterator my_iterator; 

    struct my_struct_t* test_struct = (struct my_struct_t*) malloc(sizeof(struct my_struct_t)); 
    my_iterator = test_struct->my_list.begin(); 
    printf("Beginning of list address: %p\n", my_iterator); 

    my_iterator = test_struct->my_list.end(); 
    printf("End of the list address: %p\n", my_iterator); 
    printf("Address of the list: %p\n", &(test_struct->my_list)); 

Этот код компилируется и работает нормально, но результат будет что-то вроде:

Beginning of list address: (nil) 
End of the list address: 0x86f010 
Address of the list: 0x86f010 

Последние два линии имеют для меня смысл, поскольку список должен быть пустым. Но как/почему я получаю нулевой указатель для начала? Как я могу это исправить?

+1

Шаг 1: прочитайте хороший C++-праймер, выберите один из них (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Шаг 2: поймите, что, несмотря на множество сходств, C++ и C - очень разные языки и только по-своему похожи по своим недостаткам. –

ответ

8

Вы не можете указать malloc список, а затем использовать его без инициализации. Это недопустимая операция.

Он не был инициализирован надлежащим вызовом new. То, что это работает вообще, без взрывов segfault, потрясающе.

Вам нужно будет создать объект my_struct_t с использованием инициализации стиля C++ или он не будет работать.

Вы пробовали что-то больше C++ как:

struct my_struct_t* test_struct = new my_struct_t; 

Позже вместо free позвонить вы бы delete конечно.

+1

Вам не нужен новый вызов .. но по крайней мере вызов конструктора – Kek

+1

Вызов конструктора на объект 'malloc''d кажется опасной дорогой, чтобы спуститься вниз. Если в 'list' есть деструктор, вы должны будете вызвать это вручную перед выпуском' free'. – tadman

+0

Да. Я имел в виду: вы могли бы создать свой sctruct в стеке ... или вызвать новое для структуры, а не список – Kek

1

malloc будет выделять необходимую память только для объекта, но не инициализирует этот объект. Инициализация объекта в C++ выполняется его конструктором. C++ предоставляет оператору new выделение памяти и инициализацию объекта одновременно. Так что вы должны сделать это:

my_struct_t* x = new my_struct_t(); 

Если вы действительно намеревались использовать malloc здесь, вы можете правильно инициализировать объект на правильно выровнены сырым-памяти с помощью placement new. Имейте в виду, что вам тогда придется явно вызвать деструктор и явно освободить память. Но я серьезно сомневаюсь, что это было вашим намерением.

Смежные вопросы