Visual C++: Утечка памяти

Источник: cyberguru

При создании любой программы очень важно правильно и рационально управлять памятью компьютера, которая есть у нас в распоряжении. Прежде всего, отмечу, что при написании программ в С++ используются два типа памяти: СТЕК (stack) и КУЧА (heap).

О стеке не стоит думать вообще, так как он очищается автоматически, а вот о куче надо заботиться программистам. Если, конечно, вы начинающий программист, то ваши программы не так велики и существует небольшая вероятность, что в вашей куче не останется места. Но для того, чтобы быть профессионалом, будучи ещё новичком, надо знать в каких ситуациях следует очищать кучу.

Посмотрим на следующий код:

void f ()
{
int A1[10];
int *A2=new int[5];
......
}

В нашей функции f() создаётся локальный указатель А2, который указывает на массив, размер которого достаточен для того, чтобы сохранить 5 переменных типа integer. Таким образом, автоматически выделяется место в памяти. При этом надо учесть, что когда мы создаём динамические переменные, память выделяется всегда только в куче.

Чтобы вернуть занятую память назад, следует добавить всего лишь одну строчку кода в нашу функцию:

delete[] A2;

Не забудьте, что данная строчка должна быть ни где-либо, а внутри функции, которая создаёт локальную переменную!

Что случится, если мы не позаботимся о памяти ? Ничего особенного, если у нас только одна такая функция, а если у нас подобных функций 100 или больше.

Просто в куче не останется места для выполнения всех наших операции и программа не будет работать.

Как только закончится функция f(), все локальные переменные будут удалены, А2 больше не будет существовать, но то место в куче так и будет занято, и очистить его не будет никакой возможности (исключение, если вы создатите глобальную переменную "global").

Посмотрим ещё на один пример:

class C1{
public:
C1(int size){a1=new int[size];}
~C1(){delete [] a1;}
private:
int * a1;
......
}

В конструкторе класса С1 создаётся массив, размер которого не уточняется, и может быть любым, и сколько раз будет вызываться конструктор тоже неизвестно. Таким образом, непременно в деструкторе, который автоматически вызывается в конце программы, надо очищать кучу. Следует запомнить, ВСЕГДА КОГДА КОНСТРУКТОР ВЫДЕЛЯЕТ ДИНАМИЧЕСКУЮ ПАМЯТЬ, ДЕСТРУКТОР ДОЛЖЕН ЕЁ ОЧИЩАТЬ !

И ещё одна небольшая ремарка, если вы в деструкторе поместите следующий код:

delete a1;

Не будет никакой ошибки, и возможно программа будет работать просто замечательно. Но следует учесть, что вы не очистили свою память в куче. Вы удалили всего лишь указатель а1. Квадратные скобки [] перед delete укажут компилятору, что вы хотите удалить не только указатель, а весь массив.


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=22390