У меня есть структура, в которой в качестве члена данных используется 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?
Что, вы парни, думаете?
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
Однако это ужасная идея, особенно если делать это вручную. Стандартная библиотека предоставляет поддержку распределителя - вместо этого вам следует создать распределитель, который можно легко использовать со стандартной библиотекой.
Вы также можете: struct_s obj; * tt = obj; , , , бесплатно (тт ) ;
После экспериментов: 1. С типами, отличными от POD, предложенное мной решение не будет (должно) работать. 2. Для типов, отличных от POD, если применяется вышеупомянутый механизм копирования, он начнет доступ к неинициализированной области памяти (при копировании в расположение), предполагая, что это правильно сформированные объекты, и, следовательно, вызовет ошибку сегментации. 3. Пункт 2 делает обязательной инициализацию такой искаженной памяти для данных, не относящихся к типам POD. Это в C невозможно, и мы также не встретим там такого сценария, потому что там все POD. Это причина (я думаю, одна из причин) структура C ++ сделана очень похожей на Class, так что, как предлагается в других решениях, мы можем делать соответствующие вызовы инициализации (то есть конструкторы).
Таким образом, решение состоит в том, чтобы использовать новый оператор размещения, как предложено другими.
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который будет скомпилирован с помощью компилятора C ++). Используйте тег, зависящий от версии, для вопросов, связанных с конкретной редакцией стандарта [C ++ 11], [C ++ 14], [C ++ 17] или [C ++ 20] и т. Д.