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

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

Войти
Регистрация
Восстановить пароль
 
Divergence
7 / 7 / 0
Регистрация: 19.06.2013
Сообщений: 174
#1

Управление динамической памятью при работе с классами - C++

21.06.2014, 03:11. Просмотров 629. Ответов 13
Метки нет (Все метки)

Всем привет!

Есть очень сложный класс, внутри которого есть куча указателей, в его конструкторе все эти указатели получают память при помощи оператора new, затем в декструкторе вся эта память освобождается.
В функции main я создаю указатель на свой класс, затем выделяю динамическую память под этот указатель оператором new. Когда класс перестает быть нужным, я вызываю оператор delete для него. Программа закрывается с ошибкой 0х03.
Когда я убрал оператор delete, программа начала закрываться 0х00 (как и должна).
Отсюда вопрос: деструктор неявно удаляет объект класса из динамической памяти?
Или я чего то не понял? оО
Чтобы не быть голословным, приведу пример кода:
C++
1
2
3
4
5
6
7
8
9
int main(void)
{
SuperClass* MyClass; //Создаем указатель на экземпляр класса, который содержит в себе кучу всего
MyClass = new SuperClass(); //Выделяем динамическую память под этот класс
 
//Работаем с классом MyClass
 
delete MyClass; //Судя по всему, вызывает проблемы, почему???
} //Конец программы
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.06.2014, 03:11     Управление динамической памятью при работе с классами
Посмотрите здесь:

Куда деваются одномоментные указатели, или управление памятью в работе с std::string - C++
Здравствуйте! Положим, у нас есть функция, возвращающая строку std::string, выглядящая как-то так: std::string getHome() { ...

почему при возврате объекта из метода исчезает поле с динамической памятью - C++
При выходе из метода оператора + динамическая память, которая хранится в объекте класса Vector исчезает. Как исправить эту ситуацию?...

Ошибка при работе с памятью - C++
Если ввести например 6, 0, чтобы выбросить исключение. То по завершение программы выскакивает ошибка. В чём может быть дело? Так что то про...

Ошибка при работе с памятью - C++
Написан следующий код: #include "stdafx.h" #include <iostream> #include <stdio.h> #include <math.h> #include <cstdlib> #include...

Ошибка при работе с памятью - C++
Есть класс, в котором я предпринимаю безрезультатные попытки работать с динамической памятью из-за того, что экземпляров класса может быть...

Ошибка при работе с классами - C++
Выдаёт ошибки: 1) expected primary-expression before " #include <iostream> #include <iomanip> #include <stdlib.h> using...

Ошибка с памятью при работе с двумерными массивами. - C++
{ int i, j, c, kol; n=StrToInt(Edit1->Text); m=StrToInt(Edit2->Text); for(i=0; i<n; i++) { for(j=0; j<m; j++)...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
21.06.2014, 03:41     Управление динамической памятью при работе с классами #2
Цитата Сообщение от Divergence Посмотреть сообщение
delete MyClass; //Судя по всему, вызывает проблемы, почему???
Скорее всего, потому, что:
Цитата Сообщение от Divergence Посмотреть сообщение
очень сложный класс, внутри которого есть куча указателей, в его конструкторе все эти указатели получают память при помощи оператора new
Цитата Сообщение от Divergence Посмотреть сообщение
Когда я убрал оператор delete, программа начала закрываться 0х00 (как и должна).
А если убрать это?
Цитата Сообщение от Divergence Посмотреть сообщение
//Работаем с классом MyClass
Добавлено через 1 минуту
Цитата Сообщение от Divergence Посмотреть сообщение
в его конструкторе все эти указатели получают память при помощи оператора new
В конструкторе по умолчанию?
Divergence
7 / 7 / 0
Регистрация: 19.06.2013
Сообщений: 174
21.06.2014, 03:46  [ТС]     Управление динамической памятью при работе с классами #3
Цитата Сообщение от alsav22 Посмотреть сообщение
В конструкторе по умолчанию?
В любом конструкторе.
Я так понял, что вопрос крутится вокруг динамической памяти уже внутри класса? Ее всю чистит деструктор по умолчанию.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
21.06.2014, 03:50     Управление динамической памятью при работе с классами #4
Цитата Сообщение от Divergence Посмотреть сообщение
Ее всю чистит деструктор по умолчанию.
Может он и даёт ошибку (возможно память где-то портится). Отладчик?
Цитата Сообщение от alsav22 Посмотреть сообщение
А если убрать это?
//Работаем с классом MyClass
Divergence
7 / 7 / 0
Регистрация: 19.06.2013
Сообщений: 174
21.06.2014, 04:21  [ТС]     Управление динамической памятью при работе с классами #5
Цитата Сообщение от alsav22 Посмотреть сообщение
Может он и даёт ошибку (возможно память где-то портится). Отладчик?
Создается ощущение, что он пытается удалить то, чего уже нет...
Быстро разобраться не получается.
Подскажите, то, что выделенную под класс память оператором new нужно затем ОБЯЗАТЕЛЬНО удалять верно?
Или же деструктор сделает всю работу за меня?
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
21.06.2014, 04:28     Управление динамической памятью при работе с классами #6
Цитата Сообщение от Divergence Посмотреть сообщение
выделенную под класс память оператором new нужно затем ОБЯЗАТЕЛЬНО удалять верно?
Верно, как и верно то, что такое удаление (для полей класса) может быть прописано в деструкторе.
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
21.06.2014, 06:42     Управление динамической памятью при работе с классами #7
Цитата Сообщение от Divergence Посмотреть сообщение
Создается ощущение, что он пытается удалить то, чего уже нет...
Бывает, если класс, содержащий указатели, не имеет конструктора копирования.
Divergence
7 / 7 / 0
Регистрация: 19.06.2013
Сообщений: 174
21.06.2014, 21:36  [ТС]     Управление динамической памятью при работе с классами #8
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Бывает, если класс, содержащий указатели, не имеет конструктора копирования.
оО
А можно по-подробнее???
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
21.06.2014, 21:41     Управление динамической памятью при работе с классами #9
Цитата Сообщение от Divergence Посмотреть сообщение
А можно по-подробнее???
Если класс содержит указатели, то практически обязательно он должен иметь конструктор копирования. В противном случае, к примеру при передаче параметром в функцию по значению, будет использоваться конструктор копирования по умолчанию, который скопирует указатель во временный объект. После чего два объекта будут содержать указатели на одну область памяти со всеми вытекающими.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
21.06.2014, 21:43     Управление динамической памятью при работе с классами #10
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Если класс содержит указатели, то практически обязательно он должен иметь конструктор копирования.
А так же:
Правило трёх
Croessmah
Модератор
Эксперт CЭксперт С++
13057 / 7320 / 817
Регистрация: 27.09.2012
Сообщений: 18,066
Записей в блоге: 3
Завершенные тесты: 1
21.06.2014, 21:46     Управление динамической памятью при работе с классами #11
Плюс ко всему, может лучше использовать умные указатели?
Divergence
7 / 7 / 0
Регистрация: 19.06.2013
Сообщений: 174
22.06.2014, 02:29  [ТС]     Управление динамической памятью при работе с классами #12
Ребят... или вы меня запутали или я вообще ничего не понимаю...
Провел тест, написал микро программку для тестирования сабжа.
Вот она:
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
class cTestPointer
{
public:
    int* masInt;
    float* masFloat;
 
    cTestPointer(void)
    {
        masInt = new int[64];
        masFloat = new float[128];
    }
 
    void DoSomething(void)
    {
        for(int i=0; i < 64; i++)
        {
            masInt[i] = i + 1;
        }
        for(int i=0; i < 128; i++)
        {
            masFloat[i] = i*3;
        }
        masFloat[0] = masInt[1];
    }
 
    ~cTestPointer(void)
    {
        delete [] masInt;
        delete [] masFloat;
    }
 
};
void main(void)
{
        cTestPointer *tp;
    tp = new cTestPointer();
    tp->DoSomething();
    //delete tp;    
    tp->~cTestPointer();
}
При вызове функции delete, вылезает ошибка. Почему? Ведь мы выделили место в динамической памяти, а затем освободили его. Почему оно не работает???
При явном вызове деструктора проблем нет. Но у меня в динамической памяти по прежнему остается место под класс, ведь деструктор не удаляет сам экземпляр класса - он удаляет его члены! И получается, что у меня в динамической памяти сидит экземпляр класса, который мне уже не нужен, но удалять его оттуда я не могу - delete не работает!
Кто-нибудь, объясните этот беспредел оО
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
22.06.2014, 03:30     Управление динамической памятью при работе с классами #13
Цитата Сообщение от Divergence Посмотреть сообщение
При вызове функции delete, вылезает ошибка.
Вот такой код вызывает ошибку?
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
#include <iostream>
#include <cstdlib>
using namespace std;
 
class cTestPointer
{
public:
    int* masInt;
    float* masFloat;
 
    cTestPointer(void)
    {
        cout << "cTestPointer()" << endl;
        
        masInt = new int[64];
        masFloat = new float[128];
    }
 
    void DoSomething()
    {
        for(int i=0; i < 64; i++)
        {
            masInt[i] = i + 1;
        }
        for(int i=0; i < 128; i++)
        {
            masFloat[i] = i*3;
        }
        masFloat[0] = masInt[1];
    }
 
    ~cTestPointer()
    {
        cout << "~cTestPointer()" << endl;
 
        delete [] masInt;
        delete [] masFloat;
    }
 
};
 
int main(void)
{
    cTestPointer *tp;
    tp = new cTestPointer();
    tp->DoSomething();
    delete tp;  
    //tp->~cTestPointer();
    
    system("pause");
    return 0;
}
Нет тут ошибки, и вся, выделенная в коде через new, память (в том числе и под объектом cTestPointer) освобождается. Ошибка (двойного освобождения) будет, если оставить и delete tp, и tp->~cTestPointer().
Как эта, загадочная, ошибка у вас выглядит?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.06.2014, 03:31     Управление динамической памятью при работе с классами
Еще ссылки по теме:

Ошибка с памятью при работе класса и map - C++
В общем есть класс тест class test { public: test(void); ~test(void); test(const int&amp;); private:

Повреждена куча при работе с динам. памятью. Почему? Как исправить? - C++
Приветствую всех! Такая проблема: Вот есть код. В нем периодически появляются ошибки, а иногда и не появляется, и все хорошо работает....

С++ Необъявленный идентификатор при работе с классами. (Функция сравнивает значение свойств объектов) - C++
На идентификаторы power top_speed acceleration weight по 4 раза на каждый матюкается компилятор. Как правильно сравнить их содержимое? ...

программа с динамической памятью - C++
текст программы #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;stdlib.h&gt; #include &lt;iomanip&gt; #define m 12 using namespace...

Работа с динамической памятью! - C++
Привет! Такая задача: Необходимо выделить(по N Кб) и освободить всю динамическую память. Определить время выделения и освобождения, и объем...


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

Или воспользуйтесь поиском по форуму:
Divergence
7 / 7 / 0
Регистрация: 19.06.2013
Сообщений: 174
22.06.2014, 03:31  [ТС]     Управление динамической памятью при работе с классами #14
Цитата Сообщение от alsav22 Посмотреть сообщение
Нет тут ошибки, и вся, выделенная в коде через new, память (в том числе и под объектом cTestPointer) освобождается. Ошибка будет, если оставить и delete tp, и tp->~cTestPointer().
Как эта, загадочная, ошибка у вас выглядит?
Сейчас проверил Ваш код - все работает.
Крайне странно...
Впрочем, сейчас я рад, потому что работает то, что логично и должно работать, так как если бы оно не работало, я был бы в полном замешательстве! Спасибо!
Yandex
Объявления
22.06.2014, 03:31     Управление динамической памятью при работе с классами
Ответ Создать тему
Опции темы

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