Что такое "минимальная платформа" (необходимые методы) сложного объекта (с явно malloced внутренние данные), который я хочу сохранить в контейнере STL, например. <vector>
?
Для моих предположений (пример Мелкой монеты сложного объекта):
#include <vector>
#include <cstring>
using namespace std;
class Doit {
private:
char *a;
public:
Doit(){a=(char*)malloc(10);}
~Doit(){free(a);}
};
int main(){
vector<Doit> v(10);
}
дает
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x0804b008 ***
Aborted
и в valgrind:
malloc/free: 2 allocs, 12 frees, 50 bytes allocated.
ОБНОВЛЕНИЕ:
Минимальные методы для такого объекта: (на основе ответа sbi)
class DoIt{
private:
char *a;
public:
DoIt() { a=new char[10]; }
~DoIt() { delete[] a; }
DoIt(const DoIt& rhs) { a=new char[10]; std::copy(rhs.a,rhs.a+10,a); }
DoIt& operator=(const DoIt& rhs) { DoIt tmp(rhs); swap(tmp); return *this;}
void swap(DoIt& rhs) { std::swap(a,rhs.a); }
};
Спасибо, sbi, https://stackoverflow.com/users/140719/sbi
Обратите внимание, что Чарльз идеально ответил на ваш вопрос .
В любом случае, согласно Правилу трех , ваш класс, имеющий деструктор, также должен иметь конструктор копирования и оператор присваивания.
Вот как бы я это сделал:
class Doit {
private:
char *a;
public:
Doit() : a(new char[10]) {}
~Doit() {delete[] a;}
DoIt(const DoIt& rhs) : a(new char[10]) {std::copy(rhs.a,rhs.a+10,a);}
void swap(DoIt& rhs) {std::swap(a,rhs.a);}
DoIt& operator=(DoIt rhs) {swap(rhs); return *this;}
};
Все типы, которые вы используете, должны быть CopyConstructible
и Assignable
.
CopyConstructible
для типа T
означает, что если t
является T
или const T
, то выражение T(t)
должно давать эквивалент T
исходному t
; t. ~T() должен быть допустимым (доступный деструктор); и &t
должен давать адрес t
как [const] T*
.
Присваиваемый
означает, что для T
, t
и T
значение u
, выражение t = u
должно делать t
эквивалентным u
и быть типа T&
.
Обратите внимание, что всем этим требованиям удовлетворяют простые встроенные типы и POD-структуры. Если вы делаете что-то нетривиальное в деструкторе или конструкторе, вы должны убедиться, что конструктор копирования и оператор присвоения копий сохраняют семантику эквивалентности.
Все vector
требует, чтобы объект был "назначаемым" , что означает, что ему нужны конструктор копирования, деструктор и оператор присваивания, которые генерируются по умолчанию, если вы не предоставляете их самостоятельно.
Как говорит sbi, если вам нужна одна из этих функций, вам, вероятно, понадобятся все. В вашем случае вам также необходимо предоставить конструктор копирования и оператор присваивания, чтобы избежать повреждения кучи.