У вас есть две проблемы в деструкторе globalEnviroment
- определение Элемент неизвестен, у вас нет предупреждения при компиляции?
delete data;
должно быть delete [] data;
(в текущем случае, когда вы создали экземпляр, в котором аргумент i является результатом new Items[...]
, а не * new Item
)
Первая возможность - переместить определение Item до определения globalEnviroment , также исправляя удаление:
#include <vector>
#include <string>
struct Item
{
int id;
std::vector<std::string>* names;
Item() {};
~Item ( ) {delete names;}
};
struct globalEnviroment
{
Item * data;
globalEnviroment(Item * paramData) : data(paramData){}
~globalEnviroment()
{
delete [] data;
}
};
int main ( )
{
Item * items = new Item[3];
items[0].names = new std::vector<std::string>();
items[1].names = new std::vector<std::string>();
items[2].names = new std::vector<std::string>();
globalEnviroment * ge = new globalEnviroment(items);
delete ge;
return 0;
}
Компиляция и исполнение:
pi@raspberrypi:/tmp $ g++ -pedantic -Wall -Wextra c.cc
pi@raspberrypi:/tmp $ ./a.out
Исполнение под valgrind :
pi@raspberrypi:/tmp $ valgrind ./a.out
==13369== Memcheck, a memory error detector
==13369== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13369== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==13369== Command: ./a.out
==13369==
==13369==
==13369== HEAP SUMMARY:
==13369== in use at exit: 0 bytes in 0 blocks
==13369== total heap usage: 6 allocs, 6 frees, 20,296 bytes allocated
==13369==
==13369== All heap blocks were freed -- no leaks are possible
==13369==
==13369== For counts of detected and suppressed errors, rerun with: -v
==13369== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
Вторая возможность - переместить определение деструктора после определения Item :
#include <vector>
#include <string>
struct Item;
struct globalEnviroment
{
Item * data;
globalEnviroment(Item * paramData) : data(paramData){}
~globalEnviroment();
};
struct Item
{
int id;
std::vector<std::string>* names;
Item() {};
~Item ( ) {delete names;}
};
globalEnviroment::~globalEnviroment()
{
delete [] data;
}
int main ( )
{
Item * items = new Item[3];
items[0].names = new std::vector<std::string>();
items[1].names = new std::vector<std::string>();
items[2].names = new std::vector<std::string>();
globalEnviroment * ge = new globalEnviroment(items);
delete ge;
return 0;
}
Компиляция и выполнение дают одинаковый результат
Из этого
- имея указатель (и) в своем классе (классах), вы должны позаботиться о назначении, конструкторе копирования и т. Д., Вы должны определить их.
- конструктор Item не инициализирует names в NULL, если вы не установите поле после того, как деструктор будет иметь неопределенное поведение
- вы должны предположить data , если инициализированы массивом Items или просто Item , но ваш код будет прекрасно компилироваться независимо от того, как вы вызываете его конструктор
newItem
или new Item[..]
в аргументе.
Если вы хотите сделать упражнение с помощью указателей, не останавливайтесь в начале, попробуйте дальше; -)