Как уже было сказано , вам не хватает копирующего ctor и оператора присваивания для TransactionLog. Вот упрощенная проблема:
struct A {
int *p;
A() : p (new int()) {}
~A() { delete p; }
}
Это правильно распределяет и уничтожает объект, верно? Не совсем:
void example() {
A a;
A b = a; // Missing copy ctor; could also happen when passing/returning by value.
b = a; // Same result through missing assignment operator.
assert(a.p == b.p); // Here is the problem!
// When b is destroyed, it deletes the pointer.
// When a is destroyed, it attempts to delete the deallocated pointer,
// leading to undefined behavior.
}
А вот та же проблема, которая более точно написана в вашем коде:
struct A {
map<string, int*> m;
A() {
m["abc"] = new int();
}
~A() {
for (map<string, int*>::iterator x = m.begin(); x != m.end(); ++x) {
delete x->second;
}
}
void on_commit() {
for (map<string, int*>::iterator x = m.begin(); x != m.end(); ++x) {
delete x->second;
}
m.clear();
}
}
Решение состоит в том, чтобы объявить копию ctor и оператор присваивания для вашего класса. Даже если ваш класс не подлежит копированию, вы все равно должны объявить их, но сделать их закрытыми и не определять их:
struct A {
int *p;
A() : p (new int()) {}
~A() { delete p; }
private:
A(A const&);
A& operator=(A const&);
}
Когда они закрытые, любое использование (в недоступном контексте) будет ошибкой компилятора.