У меня есть структура, в которой в качестве члена данных используется std :: list. Этот std :: list представляет собой набор std :: pair.

Вот так (внутри файла .h)

extern struct_info tt;
typedef struct_s *struct_info;
typedef 
struct struct_s {
  std::list < std::pair <char*, int> > names;
};

Я выделяю память для этой структуры в моем .cpp файле как:

tt = mem_malloc(sizeof(struct_t));

Mem_malloc - моя собственная процедура выделения памяти. Обратите внимание, что это уже сделано как extern в файле .h.

Позже, когда я пытаюсь вернуть любой элемент в список со следующим кодом:

std::pair <char*, int> myPair = std:make_pair("A", 5);
(tt->names).push_back(myPair);

Он вылетает при выполнении push_back. Я не знаю, что здесь происходит. Нужно ли мне вызывать какой-либо конструктор или инициализатор для списка в конструкторе struct_s?

Что, вы парни, думаете?

c++
-1
Hemant Bhargava 22 Окт 2018 в 16:46

2 ответа

Лучший ответ

Вы не можете просто выделить память размером sizeof(struct_t) и ожидать, что сможете использовать эту память, как если бы там существовал экземпляр struct_t - вам нужно сначала создать его. Например.

tt = mem_malloc(sizeof(struct_t));
new (tt) struct_s{}; // <- "placement `new`"

// use `tt`...

tt->~struct_s(); // <- explicit destructor call
// deallocate tt

Однако это ужасная идея, особенно если делать это вручную. Стандартная библиотека предоставляет поддержку распределителя - вместо этого вам следует создать распределитель, который можно легко использовать со стандартной библиотекой.

5
Vittorio Romeo 22 Окт 2018 в 13:51

Вы также можете: struct_s obj; * tt = obj; , , , бесплатно (тт ) ;

После экспериментов: 1. С типами, отличными от POD, предложенное мной решение не будет (должно) работать. 2. Для типов, отличных от POD, если применяется вышеупомянутый механизм копирования, он начнет доступ к неинициализированной области памяти (при копировании в расположение), предполагая, что это правильно сформированные объекты, и, следовательно, вызовет ошибку сегментации. 3. Пункт 2 делает обязательной инициализацию такой искаженной памяти для данных, не относящихся к типам POD. Это в C невозможно, и мы также не встретим там такого сценария, потому что там все POD. Это причина (я думаю, одна из причин) структура C ++ сделана очень похожей на Class, так что, как предлагается в других решениях, мы можем делать соответствующие вызовы инициализации (то есть конструкторы).

Таким образом, решение состоит в том, чтобы использовать новый оператор размещения, как предложено другими.

-2
Vivek 24 Окт 2018 в 05:03
52930951