Программа вызывает ошибку _free_dbg(block, _UNKNOWN_BLOCK);
Программа:
class Settlement {
char* name;
Land* land;
int length;
public:
Settlement() : length(1) {
name = new char[8];
strcpy(name, "noname");
land = new Land[length];
}
Settlement(int newLength) : length(newLength) {
name = new char[8];
strcpy(name, "S");
land = new Land[newLength];
}
Land& operator [](int i) {
if (i < 0 || i > length) return *land;
else return *(land + i);
}
virtual ~Settlement() {
if(name) delete[] name;
delete[] land;
};
void print() {
cout << "Settlement " << name << " print:" << endl;
for (int i = 0; i < length; i++)
{
land[i].print();
}
}
Land - базовый класс, функция print() виртуальная. Main():
Settlement s(3);
s[0] = l1;
s[1] = c1;
s[2] = b1;
s.print();
l1 - объект класса Land; c1, b1 - объекты классов-наследников land. Программа вызывает ошибку _free_dbg(block, _UNKNOWN_BLOCK); В чем проблема?
Ответы (1 шт):
Автор решения: KoVadim
→ Ссылка
У Вас в классе есть голые указатели
char* name;
Land* land
а конструктор копирования/оператор присваивания не прописан. И он сгенерирован автоматически. Каждый раз, когда Вы пишите
s[0] = l1;
происходит вызов этих сгенерированных функций. А они просто копируют указатель.
Потом приходит время деструкторов и первый объект разрушает свои вложенные переменные. Вот когда второй пытается разрушить... вот тут и получается Ваша ошибка.
Что делать?
- Почитать о правиле трех/пяти и написать недостающие функции (конструктор копий и оператор копирования).
- Либо писать на с++, а не си (правда есть некоторые преподаватели, которым это не нравится). То есть, вместо
char*использоватьstd::string, а вместоLand* land;использоватьstd::vector<Land>(это самый красивый способ, плюс он поможет избежать чехарды сstrcpyи другими штуками с ручным выделением памяти). - Либо пойти дальше и использовать умные указатели (
unique_ptr/shared_ptr), но в данной ситуации они излишние.