C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 Подробности - Утечка памяти / MFC в подробностях / Visual C++

Подробности - Утечка памяти

При создании любой программы очень важно правильно и рационально управлять памятью компьютера, которая есть у нас в распоряжении. Прежде всего, отмечу, что при написании программ в С++ используются два типа памяти: СТЕК(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 укажут компилятору, что вы хотите удалить не только указатель, а весь массив.

Материал прислала: Tanya Smola (for_tanya@hotmail.com).


| |
Автор Каев Артем.
[AD]