Форум программистов, компьютерный форум CyberForum.ru

течь памяти из вектора - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.81
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
30.05.2011, 19:51     течь памяти из вектора #1
всем добрый вечер. постарайтесь не критиковать сразу новичка. столкнулся со странным явлением
при выполнении заданий по Страуструпу. создана простая рисовалка (все на API), есть базовый объект shape и фигуры от него унаследованные. есть вектор <shape*>, создаются фигуры и помещатся в вектор.
хрянятся там, перерисовываюся (делал для пущего эксперименту интрузивный список, простой проще некуда, но это отступление), так вот, все хорошо рисуется, при уничтожении окна корректно все объекты разрушаются, память осв.(проходом по вектору указателей командой delete). и вот дальнейшее развитие - некое подобие "стрелялки", рисуется объект, а далее "выстрел", по экрану движется окружность, при достижении объекта - объект удаляется( а именно прибивается в векторе), все работает отлично, после закрытия проги все чисто. НО, все хорошо кроме объекта curve, который представяет собой последовательность объектов line. Понимаю что звучит абстрактно, уточню. line - это протсо две точки и линия меж ними, curve это vector <shape*> добавляющий в себя линии по мере движения мыши и в итоге, когда левая клавиша ап, curve добавляется к вектор <shape*> основного объекта. тиак вот повторю все нормально рисутеся и удаляется на выходе, далее все объекты (кроме курвы) при выстреле удаляются и при выходе не дают течи, но при попытке удалить curve, удаление происходит успешно но на выходе имеется утечка памяти. ОТКУДА? что течет. деструктор вызыватся правильно, список внутри curve очищается, внешний список тоже, короче все в дебаге по шагам прошел. все удаляется. откуда течь? может есть супер особенность вектора? о которой я знать не знаю. подскажите
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.05.2011, 19:51     течь памяти из вектора
Посмотрите здесь:

C++ Удаление вектора из области динамической памяти.
Дан список, элементы которого являются координатами вектора. Найти длину вектора C++
Заданный вектор А, состоящий из n элементов. Переставить компоненты вектора, размещенные после самого элемента вектора А C++
Определить количество положительных элементов вектора С(10) и заменить этим значением минимальный элемент вектора А(5) C++
STL. Функция, которая будет искать элементы большее среднего арифметического вектора и удалять их из вектора C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
30.05.2011, 20:01     течь памяти из вектора #2
Без контекста выделения и возврата памяти сказать невозможно. Текст - в студию.
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
30.05.2011, 21:55  [ТС]     течь памяти из вектора #3
постараюсь дать общую идею, так как все вкатать это ужос.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "shape.h" //здесь абстрактный класс фигуры
 
class S //это некий управляющий класс, управляет очередями сообщений заодно и отрисовкой
{
 
public:
vector<shape*> VEC // вектор содержит указатели на фигуры производные от shape - они и перерисовываются по WM_PAINT
 
S(){};
 
~S()
 {
 for(int i=0;i<VEC.size();i++)
  delete VEC[i];
 VEC.clear();
 };
}
 
 
class curve: public shape
{
public:
vector<shape*> V2;
curve(){};
~curve()
 {
 for(int i=0;i<V2.size();i++)
  delete V2[i];
  V2.clear();
 }
}
 
//привел только деструкторы дабы не громоздить и показать как очищаю векторы
//ниже создание объектов, приведу некую абстрактную функцию.
 
void make()
{
S s;
 
//создание простых фигур через конструкцию switch в ответ на выбор меню, цвета там и пр и 
//движение мыши.
//  указатели заталкиваюся в вектор класса S после того как левая клавиша отпущена.
shape* figure = new line();
s.VEC.push_back(figure);
shape* figure = new circle();
s.VEC.push_back(figure);
//в конструкторах фигур, координаты, цвет, толщина пера, тип, HRGN полигон(для определения 
//пересечений), ничего динамического, ну а ниже собственно создание curve
figure = new curve()// этот конструктор и в реале пустой
//на движение мыши 
curve.addsegment() - сюда передаются все параметры как для создания линии, координаты и пр.
//левая клавиша отжата и curve добавляется в общий вектор
s.VEC.push_back(figure)
}
 
curve.addsegment()
{
shape8 temp = new line();
V2.push_back(temp);// курва это просто набор простых линий
}
 
//расписывать рисование думаю нет смысла. итак камень преткновения
//при такой схеме все работает, рисуется удаляется, чисто.
//выстрел - летящий круг пересекает регион объекта в векторе и по этому принципу объект 
//удаляется из вектора, для простых фигур вполне прокатывает delete s.VEC[i];s.VEC[i]=0;// нет течи
//думаю не совсем верно это поскольку остается пустая ячейка в векторе
// для курвы - и удалял через *iterator, и через delete + erase() ,и через приведение указателя //shape* к curve*, и вызывал //~curve() не советуют так делать (почему?) . деструкторы 
//вызываются, все ок, объекты 
//уничтожаются, НО на выходе - течь. Стреляешь не в курву - нет течи. А с курвой прям беда.
//
сейчас я отправлю сообщение. Я новичок и оно может быть оформлено неверно. Ужо не судите. Постарался объяснить суть.

 Комментарий модератора 
Используйте теги форматирования кода!
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
30.05.2011, 22:11     течь памяти из вектора #4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "shape.h" //здесь абстрактный класс фигуры
 
class S //это некий управляющий класс, управляет очередями сообщений заодно и отрисовкой
{
 
public:
vector<shape*> VEC // вектор содержит указатели на фигуры производные от shape - они и перерисовываются по WM_PAINT
 
S(){};
 
~S()
{
for(int i=0;i<VEC.size();i++)
delete VEC[i];
VEC.clear();
};
}
 
 
class curve: public shape
{
public:
vector<shape*> V2;
curve(){};
~curve()
{
for(int i=0;i<V2.size();i++)
delete V2[i];
V2.clear();
}
}
 
 
//привел только деструкторы дабы не громоздить и показать как очищаю векторы
//ниже создание объектов, приведу некую абстрактную функцию.
 
void make()
{
S s;
 
//создание простых фигур через конструкцию switch в ответ на выбор меню, цвета там и пр и
//движение мыши.
// указатели заталкиваюся в вектор класса S после того как левая клавиша отпущена.
shape* figure = new line();
s.VEC.push_back(figure);
shape* figure = new circle();
s.VEC.push_back(figure);
//в конструкторах фигур, координаты, цвет, толщина пера, тип, HRGN полигон(для определения
//пересечений), ничего динамического, ну а ниже собственно создание curve
figure = new curve()// этот конструктор и в реале пустой
//на движение мыши
curve.addsegment() - сюда передаются все параметры как для создания линии, координаты и пр.
//левая клавиша отжата и curve добавляется в общий вектор
s.VEC.push_back(figure)
}
 
curve.addsegment()
{
shape* temp = new line();
V2.push_back(temp);// курва это просто набор простых линий
}
 
//расписывать рисование думаю нет смысла. итак камень преткновения
//при такой схеме все работает, рисуется удаляется, чисто.
//выстрел - летящий круг пересекает регион объекта в векторе и по этому принципу объект
//удаляется из вектора, для простых фигур вполне прокатывает delete s.VEC[i];s.VEC[i]=0;// нет течи
//думаю не совсем верно это поскольку остается пустая ячейка в векторе
// для курвы - и удалял через *iterator, и через delete + erase() ,и через приведение указателя //shape* к curve*, и вызывал //~curve() не советуют так делать (почему?) . деструкторы
//вызываются, все ок, объекты
//уничтожаются, НО на выходе - течь. Стреляешь не в курву - нет течи. А с курвой прям беда.
//
Во-первых, меня смущает:
C++
1
curve.addsegment()
Ведь у тебя указатель. Поэтому figure->addsegment() надо писать.
Во-вторых, у тебя добавляется в вектор и figure для curve, и внутри addsegment() еще создается один динамический объект и тоже добавляется в вектор.
В-третьих, при удалении фигуры, ты память освобождаешь, но из вектора не удаляешь элемент, а просто обнуляешь его.
А потом в деструкторе еще раз вызывается возврат памяти.
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
30.05.2011, 22:58  [ТС]     течь памяти из вектора #5
да конечно. -> сорри это тут видимо спешил. все верно вектор в нем указатели на объекты, внтури curve - тоже вектор тоже с указателями на объекты в куче. признаю ошибку по поводу обнуления элемента основного вектора, но разве при выходе из программы и разрушении вектора - не будет удален и этот нулевой, пустой элемент?
далее. я пробовал и erase(), т.е. не было пустых элементов. Обнуление делал для того чтобы работали условия такого плана if(!s.VEC[i]) что то делаем.

дошло до того что я стал создавать только одну фигуру curve и удалять ее delete s.VEC[i]; далее затирать данную позицию erase() или еще лучше s.VEC.clear(); вектор показывал что его размер 0, до трюков со сжатием я еще не дошел, и его объем остался 1.
и....при закрытии течь.
постараюсь выделить главное.
1. проверка показала что при delete s.VEC[i] вызыватся ~curve() и внутренний список очищается.
значит curve чиста, течь не в ней так? (при простом рисованиии все списки удаляются по той же схеме и течи нет, т.е. я нарисовал дом, траву и людей, создал с десяток curve и при закрытии окна вызваются эти 10 ~curve() и все чисто)
2. именно при попытке удалить искуственно элемент общего вектора и именно если этот элемент curve, при закрытии память утекает
Detected memory leaks!
Dumping objects ->
{234} normal block at 0x003661C0, 8 bytes long.
Data: < {6 > D4 7B 36 00 00 00 00 00
{233} normal block at 0x00367BA0, 72 bytes long.
Data: < B > B4 E9 42 00 CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

Я так понимаю вопрос можно свести к такому. как правильно удалить объект используя указатель на него хранящийся в любой части вектора, при условии что объект в куче и сам внутри содержит вектор указателей на объекты кучи.Что из того что я написал в деструкторах не работает?

Добавлено через 15 минут
Валерий, может у меня глаз замылился и не понимаю чего то элементарного?
на каждый new объект приходится и delete. и при последовательном очищении как, внешнего так и внутреннего вектора(curve) все хорошо. но стоит "выстрелом" удалить вручную элемент вектора и если этот элемент curve то вот такая беда.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
30.05.2011, 23:53     течь памяти из вектора #6
Цитата Сообщение от AzaKendler Посмотреть сообщение
Валерий, может у меня глаз замылился и не понимаю чего то элементарного?
на каждый new объект приходится и delete. и при последовательном очищении как, внешнего так и внутреннего вектора(curve) все хорошо. но стоит "выстрелом" удалить вручную элемент вектора и если этот элемент curve то вот такая беда.
Прежде, чем саму курву удалять не нужно ли удалить все внутренние у нее объекты? Как я понимаю, ты там тоже делаешь new(). Поэтому нужно сначала сделать delete() для всех таких объектов, а потом уже curve делать erase. Иначе - потерянные ссылки возникают - та самая утечка памяти...
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
31.05.2011, 00:19     течь памяти из вектора #7
auto_ptr спасет отца русской демократии?
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
31.05.2011, 00:25     течь памяти из вектора #8
Цитата Сообщение от lemegeton Посмотреть сообщение
auto_ptr спасет отца русской демократии?
Ну, или другой интеллектуальный указатель, например shar_ptr
slice
32 / 75 / 4
Регистрация: 04.11.2010
Сообщений: 249
31.05.2011, 00:28     течь памяти из вектора #9
нубасы, я по первому посту догадался, что автор забыл виртуальный деструктор
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
31.05.2011, 08:45     течь памяти из вектора #10
Цитата Сообщение от slice Посмотреть сообщение
нубасы, я по первому посту догадался, что автор забыл виртуальный деструктор

Не по теме:

Так вот ты какой - Северный Олень!

AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
31.05.2011, 12:31  [ТС]     течь памяти из вектора #11
спасибо всем за ответы огромное. но хочу уточнить. объекты внутри курвы удаляются в ее деструкторе. тут все ок. т.е. когда она дергается на удаление из основного списка - вызывается ее деструктор, а в нем чистится внутренний список. Это касается и виртуальных деструкторов - я проверял - вызывается именно нужный деструктор, ~curve() и в нем чистится список содержащий линии составляющие кривую.
поскольку все объекты стремятся разрушится на выходе из проги, то дергаются деструкторы в которых я очищаю то, что насоздавал в куче. повторю что при простом рисовании - создай хоть 50 curve, каждая из сотен сегментов - на выходе все чисто. Проблем именно с удалением из вектора по позиции.
Или я не уловил совет? Предлагается принудительно очистить списоk curve? он ведь и так в деструкторе чистится.

по поводу auto_ptr - каюсь, я новичок и не дочитал еще до них. Уже жалею что переделал все на вектор вместо своего интрузивного списка, там было все очень просто и видно что почем, но была другая причина почему я переделал на вектор(это отдельная тема, хотел проверить кое что). пока непонятно в чем причина. буду тестировать сегодня еще. Это тестовая прога так сказать, никаких бизнес критикал, но прсто очень хочется понимания а не так все бросить и дальше что то делать.

Добавлено через 1 час 43 минуты
в общем то выписанные на бамажку адреса указателей дали следующее

{187} normal block at 0x00366158, 8 bytes long.
Data: <Lo6 > 4C 6F 36 00 00 00 00 00
{186} normal block at 0x00366F18, 72 bytes long.
Data: < B > B4 E9 42 00 CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

оба объекта по адресам расположены в пределах куска памяти под curve.

второй объект это ВСЕГДА некий "несуществующий" объект находящийся за пределами последнего элемента вектора. например я создал 38 элементов а на выходе получил течь с адресом 39-го, создал 39 - получил течь адреса 40-го, это немного странно.
учитывая что новые элементы добавляются к вектору только стандартными операциями push никакого случайного добавления быть не может.

по первому адресу непонятно - он лежит в диапазоне куска выделенного под curve где то между 7 и 8 элементом. с чего бы это?

вся данная ситуация только при попытке ручного удаления curve из основного вектора.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
31.05.2011, 18:06     течь памяти из вектора #12
AzaKendler, а поставь-ка ты в конструкторы и деструкторы диагностическое сообщение. И смотри, не создаются ли у тебя временные объекты.
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
31.05.2011, 19:43  [ТС]     течь памяти из вектора #13
Валерий, в битве СТАНДАРТОВ и человека, победили СТАНДАРТЫ), вектор оказался ни при чем, в одном из обработчиков мыши я нашел баг, именно при таком сочетании создавался пустой curve и помещался в вектор, он и тек. Добавил условие и все. Прекрасный язык С++, приучает к вниманию в мелочах и деталях. И не так страшен чОрт ка его малюют, стоит сесть и еще более внимательно проанализировать и вот, нате. Ошибочка.
Спасибо что выслушали и я рад, что зарегился на таком отличном форуме!
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
31.05.2011, 19:49     течь памяти из вектора #14
AzaKendler, диагностические сообщения в конструкторах - рулят! Сразу видать лишние вызовы конструкторов. А если еще макросы _LINE_ и _FILE_ использовать, то вообще отличная диагностика выходит!
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
31.05.2011, 19:54  [ТС]     течь памяти из вектора #15
Я пока не успел ими воспользоваться.Увидел поздновато. Но теперь буду знать, сэкономил бы время.
Задам параллельно вопрос - насколько я понял количество HDC в WIndows ограничено, а как сократить создание контекстов? Передавать ссылки? НDC - это по моему и так указатель.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
31.05.2011, 20:13     течь памяти из вектора #16
Ну, до сих пор с количеством HDC вроде ни у кого проблем не возникало...
Handle to a device context (DC).
This type is declared in WinDef.h as follows:
typedef HANDLE HDC;
HANDLE
Handle to an object.
This type is declared in WinNT.h as follows:
typedef PVOID HANDLE;
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
31.05.2011, 20:44  [ТС]     течь памяти из вектора #17
дескриптор кончено, не указатель. да, вопрос размыт. в любом случае приятно общение с экспертом
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
31.05.2011, 21:34     течь памяти из вектора #18
Цитата Сообщение от AzaKendler Посмотреть сообщение
дескриптор кончено, не указатель. да, вопрос размыт. в любом случае приятно общение с экспертом
Вообще-то PVOID как раз намекает, что указатель...
Просто можно дальше полезть в виндовские типы и расшифровать полностью. Но и так понятно, что это вроде "pointer_to_void"
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
31.05.2011, 23:15     течь памяти из вектора #19
Цитата Сообщение от AzaKendler Посмотреть сообщение
Задам параллельно вопрос - насколько я понял количество HDC в WIndows ограничено
ну если почитать юань феня, то да, ограничено
Цитата Сообщение от AzaKendler Посмотреть сообщение
а как сократить создание контекстов
о каком случае речь идет? при рисовании в WM_PAINT'e система сама предоставляет контекст
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.06.2011, 08:50     течь памяти из вектора
Еще ссылки по теме:

Составить главную программу и функцию. Для данного вектора А(М) найти количество неповторяющихся элементов вектора C++
C++ Динамическое выделение памяти для Вектора ( не STL)
C++ Ошибка при резервировании памяти для своего(!) вектора

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
01.06.2011, 08:50  [ТС]     течь памяти из вектора #20
речь идет о том, что в этой жешь "рисовалке" , описанной выше, когда количество объектов в векторе(то бишь нарисованных на экране) становится велико - например замулевать курвой всу окошко в несколько слоев, то происходит сбой такого плана, что изображение выходит за рамки окна, неверно отображается цвет, в виндоувзз на экране остается пятно, при закрытии рисовалки, на панелях запуска пятна. исчезающие при разворачивании сворачивании других окон. Я предположил, что неправильно использую контекст и где то не овсобождаю его, и в процессе рисования программа забирает все свободные контексты. ReleaseDC - присутствует при выходе из цикла сообщений. В процедурках старался использовать передачу HDC& - хотя возможно это неправильно, если это правильно, то мог где-то упустить&, еще не проверял пошагово. вот такой собственно вопрос.
Yandex
Объявления
01.06.2011, 08:50     течь памяти из вектора
Ответ Создать тему

Метки
местные умники жгут)))
Опции темы

Текущее время: 05:11. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru