Noob. C++ memory leak

uaha1979

Добрый день.
Прогаю на С++, ОС: линукс, IDE: NeatBean
Есть ли утилита для проверки memory leak?
Есть ли функция, которая показыват сколько памяти выделено на данный момент для программы?
(Запускаю функцию в начале, запускаю в конце, если разница не 0, ищу где текет).
Еще такой вопрос:
Как правильно почистить list и vector?
Clear вроде не всегда работает (почему не понятно, и зачем нужен этот метод?).
Например если есть vector<vector<struct *> *>
Я бы хотел делать так (но не знаю насколько это правильно, и почистится ли вся выделенная память):

for (int i = 0; i < curPoint->border->size; i++){
for (int j = 0; j < curPoint->border[i][j]->size; j++ ){
free(curPoint->border[i][j]); //free struct
}
free(curPoint->colorBorder[i]->clear;
}
free(curPoint->colorBorder->clear;

okis

Valgrind
Гуй у него тоже какой-то бывает
Можно включить отладочный режим менеджера памяти

okis

В куске кода скобки не сходятся и вообще что-то странное
Что значит "не работает"?

agaaaa

а) Ты точно уверен, что тебе нужны указатели?
б) используй shared_ptr

Serab

free(curPoint->colorBorder[i]->clear;
что это должно значить?

iravik

vector<vector<struct *> *>
адок

Serab

сделай vector<vector<struct>> и ничего удалять не надо будет вообще.

uaha1979

Прошу прощение за не полный и не точный кусок кода.

curPoint = new vector<vector<double *> *>;//указатель на мой массив
Цикл{
border = new vector<struct *>;
curPoint->push_back(border);
Цикл{
d = new struct;;
d->... = ...
d->... = ...
border->push_back(d);
}
}

free(curPoint->colorBorder[i]->clear;
что это должно значить?
free не нужно. Тупанул
должно быть так:

for (int i = 0; i < curPoint->border->size; i++){
for (int j = 0; j < curPoint->border[i][j]->size; j++ ){
free(curPoint->border[i][j]); //free struct
}
curPoint->colorBorder[i]->clear;
}
curPoint->colorBorder->clear;

по факту у меня двумерный массив, который может динамически менять размер, элементами массива являются структуры struct.
первый цикл: идем по столбцам{
второй цикл: идем по строчкам{
очищаем память выделенную под структуру, которая хранится на месте i j
}
очищаем память, выделенную под столбец
}
очищаем память, выделенную под строку.
Меня смущает следующее:
На сайте http://www.cplusplus.com/reference/vector/vector/clear/
std::vector::clear
Removes all elements from the vector (which are destroyed leaving the container with a size of 0.
A reallocation is not guaranteed to happen, and the vector capacity is not guaranteed to change due to calling this function. A typical alternative that forces a reallocation is to use swap:

vector<T>.swap(x); // clear x reallocating
С этой поправкой возникает вопрос: мой код очистит всю память всегда, иногда будет очищать иногда нет или никогда не будет чистить память?
сделай vector<vector<struct>> и ничего удалять не надо будет вообще.
делать так?

curPoint = <vector<vector<struct> >;
Заполнение, работа с curPOoint
...
delete [] curPoint;

правильно ли я понимаю, что он рекурсивно очистит всю память?

agaaaa

delete [] curPoint;
Это вообще не нужно с vector<vector<struct>>. Не напишешь ни одного new - не понадобится ни 1 delete

PooH

сделай vector<vector<struct>> и ничего удалять не надо будет вообще.
а вдруг эта структура тяжелая или в ней хендлы и указатели
зачем ее копировать в вектор
просто в таком случае просто надо понять, кому эти структуры принадлежат
потом в куче их создавать, указатели класть в вектор
когда надо что-то удалить - вытаскиваем указатель из вектора, структуру удаляем через delete

PooH

подскажите, кстати
Struct p = new struct;
...
free(p);
я может чего-то не понимаю, но тут потенциально память утекает если в структуре что-то динамически создается
если хочешь в С писать
Struct* p = (Struct*)malloc(sizeof(Struct;
// инициализируем поля
...
free(p);

margadon

Struct p = new struct;
...
free(p);
это как-то неправильно, выделять new а удалять free
если в структуре что-то динамически создаётся, то оно же должно в деструкторе структуры и удаляться, тогда будет чисто

Ivan8209

Более того, коду разрешено падать при таком насилии над здравым смыслом.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."

PooH

это как-то неправильно, выделять new а удалять free
я о том же и говорю
в коде ТС вроде так (не вчитывался)

PooH

ну и соот-но почитай про RAII, чтобы избавиться от головной боли
PS если тебе нужен двумерный вектор, то зачастую вектор векторов - это не то, что тебе нужно
почитай, как обычно делают в твоем случае

Serab

я может чего-то не понимаю, но тут потенциально память утекает если в структуре что-то динамически создается
деструктор не вызовется по факту. А на самом деле это UB, естественно.

PooH

ну и соот-но плюсы - это такой язык, в котором в одной строчке можно прострелить себе ногу в трех местах и заметить это только через месяц

PooH

кстати, недавно на собеседовании в одну очень серьезную компанию попался такой вопрос:
Base и Derived классы
Derived включает в себя int'ы, к примеру (в общем случае POD-типы)
у базового класса есть virtual метод который в derived переопределен под return int;
нужен ли в данном случае виртуальный деструктор?
если не нужен, обосновать отсутствие утечек памяти

Maurog

попался такой вопрос
что примечательного в этом мутно сформулированном вопросе? :grin:

Serab

у базового класса есть virtual метод который в derived переопределен под return int;
WAT

uaha1979

Спасибо за ответы.
По поводу утечки памяти:
Есть ли функция, которая показывает сколько памяти выделено на данный момент для программы?
(Вызываю функцию в начале, запускаю в конце, если разница не 0, ищу где текет).

PooH

 
 
class Base {
public:
Base {}
~Base {}
virtual int get {return 0;}
}

class Derived : public Base {
int Int;
public:
Derived : Base {}
~Derived {}
int get {return Int;}
}

//-------

Base* p = new Derived;
...
delete p;

PooH

что примечательного в этом мутно сформулированном вопросе?
да, в принципе, ничего
вопрос на понимание виртуальных методов и как объект выглядит в памяти

uaha1979

code:

class Base {
public:
Base;
...
Поясни, пожалуйста.

Maurog

code:
теперь вопрос не мутный и короткий ответ на него : UB :grin:

PooH

Поясни, пожалуйста.
что именно?

PooH

теперь вопрос не мутный и короткий ответ на него : UB
вопрос в том, надо ли делать ~Derived виртуальным
почему UB?

uaha1979

что именно?
Как мне узнать сколько памяти выделено под проект в начале, сколько в конце.

PooH

Как мне узнать сколько памяти выделено под проект в начале, сколько в конце.
я обычно делаю так, если надо проверить:
Base* p = new Base;
Base* old = p;
delete p;
Base* p2 = new Base;
assert(old == p2);
с отключенном оптимизацией, конечно, со стандартным аллокатором и если мне надо быстренько проверить
более строгая проверка немного по-другому делается

Maurog

почему UB?
согласно стандарту C++03/C++11 удаление с помощью delete через указатель на базу, не имеющей виртуальный деструктор - UB
цитаты привести?:)

uaha1979

более строгая проверка немного по-другому делается
Можешь кинуть ссылку или сказать, что читать?

Serab

Тебе уже советовали valgrind либо другие специальные инструменты для этого. Не надо считать "в начале" и "в конце" и сравнивать, надо пользоваться правильными инструментами для задачи.

uaha1979

ok

istran

Читай любую не очень старую книгу по C++ (и перед этим желательно по C). Похоже у тебя в голове каша, и утечки памяти это лишь следствие.

ava3443

вопрос в том, надо ли делать ~Derived виртуальным
Странный вопрос: если ~Base виртуальный, то и ~Derived автоматически будет таким же, независимо от того напишешь ты virtual перед ним, или нет.
Ну или вопрос не странный, а просто задали чтобы понять, чувствуешь ли ты разницу между читаемым кодом и нечитаемым.

Serab

а вдруг эта структура тяжелая или в ней хендлы и указатели
это вообще не факторы. Вот просто вообще не связанные вещи. Указатели может быть надо хранить если:
1) происходит переупорядочивание элементов этого массива (сортировка когда хочется сэкономить на копировании.
2) за выделение памяти под них отвечает некоторая другая структура, в которую необходимо хранить указатели (обычно это все равно следствие 1
"Тяжесть" структур в легкую компенсируется сокращением количества динамических аллокаций, требуемых для инициализации и упрощением получаемого кода.

PooH

Странный вопрос: если ~Base виртуальный, то и ~Derived автоматически будет таким же, независимо от того напишешь ты virtual перед ним, или нет.
Ну или вопрос не странный, а просто задали чтобы понять, чувствуешь ли ты разницу между читаемым кодом и нечитаемым.
блин, я не совсем то, что надо написал
вопрос был в том, что делать ли ~Base виртуальным

agaaaa

а вдруг эта структура тяжелая или в ней хендлы и указатели
зачем ее копировать в вектор
Имхо, это лучше, чем разбираться с утечками.
И не факт, что будут потери производительности.
Послушай совета, убери указатели, если возможно.

apl13

Нет, так:
у базового класса есть virtual метод который в derived переопределен под return int;
нужен ли в данном случае виртуальный деструктор?
NaNNaNNaNNaNNaNNaNNaNNaN WAT?
Оставить комментарий
Имя или ник:
Комментарий: