Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Gepar
1178 / 534 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
#1

Течёт память рекой - C++

18.04.2012, 21:00. Просмотров 362. Ответов 5
Метки нет (Все метки)

Не могу понять в чём проблема. Есть класс CControl, от него есть наследники CInput и CButton. Просто создание объектов типа CButton и CInput не возникает утечек памяти, использование функции Clone для получения копии объекта (и последующее освобождение памяти через delete) тоже проблем не возникает, а вот когда возникает необходимость хранить объекты наследники CControl в классе CWindow в списке то тут же начинает течь память.

Класс CControl и его наследник. Класс CControl виртуальный, а CButton вполне реальный. У обоих классов есть только статические элементы( за исключением результата работы функции Clone). Виртуальный деструктор я и там и там указал что он есть и он необходим.

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
72
73
class CControl
{
public:
    CControl(int _ID, double xPos1, double yPos1, double xPos2, double yPos2,  const string& _type, const string& _title="")
    :ID(_ID), type(_type), title(_title), x1(xPos1), y1(yPos1), x2(xPos2),y2(yPos2),printFromWindow(false),specialCBprint(false){}
 
    virtual void Print(ostream& os) const
    {
        if(printFromWindow==true)
         os<<"+- ";
 
        os<<"["<<ID<<"]"<<" "<<type<<" "
        <<"\""<<title<<"\" "
        <<"("<<x_1<<","<<y_1<<","
        <<x_2<<","<<y_2<<")"<<endl;
    }
 
    friend ostream& operator<<(ostream& os, const CControl& right)
    {
        right.Print(os);
        return os;
    }
 
    virtual CControl* clone() const =0; //функция, которую должны переопределять наследники
 
    int ID;// our ID
    string type;// Button/Label
    string title;//"Ok" /"Cancel"
 
    //coordinats
    double x1;
    double y1;
    double x2;
    double y2;
 
    //real coordinats to print
    //setted by CWindow
    int x_1;
    int y_1;
    int x_2;
    int y_2;
 
    //+-
    bool printFromWindow;
 
    //|  +-
    bool specialCBprint;
 
    virtual ~CControl()
    {
 
    }
 
};
 
 
 
[CPP]class CButton: public CControl
{
public:
    CButton(int ID, double xPos1, double yPos1, double xPos2, double yPos2, const string& title)
    :CControl(ID, xPos1, yPos1, xPos2, yPos2, "Button", title) {}
 
    virtual CControl* clone() const
    {
        return new CButton(*this);
    }
 
    virtual ~CButton()
    {
 
    }
};
[/CPP]


Класс окно, который держит список контролов:
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
72
class CWindow
{
private:
    //coordinats
    int fx1;
    int fy1;
    int fx2;
    int fy2;
 
    string title;
 
    int countCB;//how many CCombobox we have
 
    //структура чтобы список контролов держать
    struct ListControl
    {
        ListControl()
        :control(NULL), next(NULL){}
 
        ListControl(const CControl& cont)
        :control(cont.clone()), next(NULL) {}
 
        CControl* control;
        ListControl* next;
    } * head, *tail;
 
 
 
public:
    CWindow(const string& _title, int xPos1, int yPos1, int xPos2, int yPos2)
    :fx1(xPos1), fy1(yPos1), fx2(xPos2), fy2(yPos2), title(_title), countCB(0), head(NULL), tail(NULL) {}
 
 
    ~CWindow()
    {
        ListControl* temp= head;
        ListControl* del;
        while(temp)
        {
            del= temp;
            temp= temp->next;
            delete del;
        }
        head=tail=0;
    }
 
 
    //метод добавления контрола в список
    CWindow& Add(const CControl& obj)
    {
        if(! head)
        {
            head= tail= new ListControl;
            head->control= obj.clone();
            Recalculate(head->control);//масштабирование и прочая ерунда, меняет значения в control, ничего не создаёт и не удаляет
            head->next= NULL;
 
            ///if(dynamic_cast<CComboBox*> (head->control))
            /// countCB++;
        }
 
        else
        {
            ListControl* toAdd= new ListControl;
            toAdd->control= obj.clone();
            toAdd->next= NULL;
            Recalculate(toAdd->control);
            tail->next= toAdd;
            tail= toAdd;
        }
        return *this;
    }

Укажите на ошибку, ато я её в упор не вижу и не могу понять что не так. В мейне если просто создаю объект окно - всё ок, если только добавляю кнопку в окно через Add то получаю в итоге утечки памяти.
В мейн делаю вот так:
C++
1
2
3
4
5
int main()
{
    CWindow a( "Test X", 751, 245, 400, 700 );
    a.Add( CButton ( 1, 0.1, 0.8, 0.3, 0.1, "Ok" ));
}
Тоесть идёт вызов конструктора по умолчанию -> метода Add где всё идёт по первой ветке if (там же вызывается метод Clone от CButton) ну и вызов деструктора. Куда же уходит память ?
Тестирую валгриндом (+ сервер выдаёт мне пенальти за память так что валгринд видать не обманывает).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.04.2012, 21:00
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Течёт память рекой (C++):

Статическая память,Динамическая память. - C++
a) Статическая память. Двумерный массив. Дан массив целых чисел. В массиве есть отрицательные числа. Определить координаты левого нижнего...

Realloc выделяет память для массива int и не выделяет память для массива double - C++
Скажите пожалуйста, почему вот этот код работает: #include &lt;iostream&gt; #include &lt;windows.h&gt; using namespace std; int main()...

Течёт Canon Е404 pixma - Принтеры, МФУ
Здравствуйте! У меня такая ситуация - установил бесперебойник и теперь сочится краска из сопла определённого цвета во время простоя...

Когда ставишь память в DIMM2, при этом приходится память переворачивать - Оперативная память
Помогите мне. При добавление памяти в столкнулся с проблемой. Когда память стоит в DIMM1 (фото 1) всё работает хорошо. Когда ставишь эту...

Разделяемая память POSIX IPC как узнать, что память выделена и её уже можо использовать? - C Linux
1. Описание проблемы: Две программы. Одна пишет в разделяемую память, другая читает. Из-под читающей программы read невозможно понять...

Почему в TASM нельзя сравнивать память-память? - Assembler
То есть я понимаю, что можно либо регистр-память, либо память-регистр, либо регистр-регистр. Но почему так? И существуют ли методы, как это...

5
Rotfeder
35 / 0 / 1
Регистрация: 18.04.2012
Сообщений: 3
18.04.2012, 22:01 #2
Мне кажется, что нет delete для ListControl::control
0
Gepar
1178 / 534 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
18.04.2012, 22:30  [ТС] #3
Rotfeder, большое спасибо! Оно на определённом этапе когда код написал то некоторые элементарные вещи перестаёшь замечать, как вот здесь например
0
Ree.exe
56 / 56 / 4
Регистрация: 01.08.2011
Сообщений: 141
18.04.2012, 22:33 #4
Цитата Сообщение от Gepar Посмотреть сообщение
~CWindow()
* * {
* * * * ListControl* temp= head;
* * * * ListControl* del;
* * * * while(temp)
* * * * {
* * * * * * del= temp;
* * * * * * temp= temp->next;
* * * * * * delete del;
* * * * }
* * * * head=tail=0;
* * }
Да ты ведь не удаляешь на что указывает поле control
Что-то такое должно быть:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
~CWindow()
* * {
* * * * ListControl* temp= head;
* * * * ListControl* del;
* * * * while(temp)
* * * * {
* * * * * * del= temp;
* * * * * * temp= temp->next;
            delete del -> control;
* * * * * * delete del;
* * * * }
* * * * head=tail=0;
* * }
1
Gepar
1178 / 534 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
18.04.2012, 23:24  [ТС] #5
Ree.exe, ну собственно об этом уже Rotfeder выше написал...
0
Ree.exe
18.04.2012, 23:40     Течёт память рекой
  #6

Не по теме:

да уж заметел

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.04.2012, 23:40
Привет! Вот еще темы с ответами:

Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена - C#
При добавлении dataGridView(Visual Studio 2010) выдает ошибку &quot;Попытка чтения или записи в защищенную память. Это часто свидетельствует о...

Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена - C#
При нажатии на пробелы выскакивает ошибка ( Application.Run(new Form5()); - Попытка чтения или записи в защищенную память. Это часто...

Внутренняя память 0.00 МБ. Не видит внутреннюю память - Android
Здраствуйте, девайс Prestigio Multipad PMP5670c_DUO. Я пытался найти способ решения проблемы, или найти прошивку, но толком ничего не...

Оперативная память и видео память, связь ? - Mac OS
Доброго времени суток, уважаемые! Являюсь обладателем следующей машинки: MacBook Pro 13 дюймов, конец 2011 года. Сделал небольшой...


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

Или воспользуйтесь поиском по форуму:
6
18.04.2012, 23:40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.