Всего книг:

826

Последнее обновление:

 2008-07-25 16:42:12

 

Искать

 

Нас считают!


Яндекс цитирования

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Учимся программировать на языке C++ : Использование свободной памяти в С++

Allk.Ru - Все книги!

 

 

 

Учимся программировать на языке C++:Использование свободной памяти в С++

  Как вы уже знаете, если ваша программа объявляет массив, компилятор C++ распределяет память для хранения его элементов. Однако представляется возможным, что до некоторого времени размер массива может быть не так велик, чтобы вместить все необходимые данные. Например, предположим, что вы создали массив для хранения 100 акций. Если позже вам потребуется хранить более 100 акций, вы должны изменить свою программу и перекомпилировать ее. С другой стороны, вместо распределения массива фиксированного размера ваши программы могут запрашивать необходимое количество памяти динамически, т.е. во время выполнения. Например, если программе необходимо следить за акциями, она могла бы запросить память, достаточную для хранения 100 акций. Аналогично, если программе необходимы только 25 акций, она могла бы запросить меньше памяти. Распределяя подобным образом память динамически, ваши программы непрерывно изменяют свои потребности без дополнительного программирования. Если ваши программы запрашивают память во время выполнения, они указывают требуемое количество памяти, а C++ возвращает указатель на эту память. C++ распределяет память из областей памяти, которые называются свободной памятью. В этом уроке рассматриваются действия, которые должна выполнить ваша программа для динамического распределения, а впоследствии освобождения памяти во время выполнения. К концу данного урока вы освоите следующие основные концепции:

* Чтобы запросить память во время выполнения, ваши программы должны использовать оператор C++ new.
* При использовании оператора new программы указывают количество требуемой памяти. Если оператор new может успешно выделить требуемый объем памяти, он возвращает указатель на начало области выделенной памяти.
* Если оператор new не может удовлетворить запрос на память вашей программы (возможно, свободной памяти уже не осталось), он возвращает указатель NULL.
* Чтобы позже освободить память, распределенную с помощью оператора new, ваши программы должны использовать оператор C++ delete.

Динамическое распределение памяти во время выполнения является чрезвычайно полезной возможностью. Экспериментируйте с программами, представленными в данном уроке. И вы поймете, что динамическое распределение памяти реально выполняется очень просто.
ИСПОЛЬЗОВАНИЕ ОПЕРАТОРА new

Оператор C++ new позволяет вашим программам распределять память во время выполнения. Для использования оператора new вам необходимо указать количество байтов памяти, которое требуется программе. Предположим, например, что вашей программе необходим 50-байтный массив. Используя оператор new, вы можете заказать эту память, как показано ниже:

char *buffer = new char[50];

Говоря кратко, если оператор new успешно выделяет память, он возвращает указатель на начало области этой памяти. В данном случае, поскольку программа распределяет память для хранения массива символов, она присваивает возвращаемый указатель переменной, определенной как указатель на тип char. Если оператор new не может выделить запрашиваемый вами объем памяти, он возвратит NULL-указатель, который содержит значение 0. Каждый раз, когда ваши программы динамически распределяют память с использованием оператора new, они должны проверять возвращаемое оператором new значение, чтобы определить, не равно ли оно NULL.

Зачем необходимо динамически распределять память с использованием new

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

Вместо редактирования и перекомпилирования программ, которые просто запрашивают память с запасом, вам следует создавать свои программы таким образом, чтобы они распределяли требуемую им память динамически во время выполнения, используя оператор new. В этом случае ваши программы могут адаптировать использование памяти в соответствии с вашими изменившимися потребностями, избавляя вас от необходимости редактировать и перекомпилировать программу.

Например, следующая программа USE_NEW.CPP использует оператор new для получения указателя на 100-байтный массив:

#include

void main(void)

{
char *pointer = new char[100];
if (pointer != NULL) cout << "Память успешно выделена" << endl;
else cout << "Ошибка выделения памяти" << endl;
}

Как видите, программа сразу проверяет значение, присвоенное оператором new переменной-указателю. Если указатель содержит значение NULL, значит new не смог выделить запрашиваемый объем памяти. Если же указатель содержит не NULL, следовательно, new успешно выделил память и указатель содержит адрес начала блока памяти.

Если new не может удовлетворить запрос на память, он возвратит NULL

При использовании оператора new для выделения памяти может случиться так, что ваш запрос не может быть удовлетворен, поскольку нет достаточного объема свободной памяти. Если оператор new не способен выделить требуемую память, он присваивает указателю значение NULL. Проверяя значение указателя, как показано в предыдущей программе, вы можете определить, был ли удовлетворен запрос на память. Например, следующий оператор использует new для распределения памяти под массив из 500 значений с плавающей точкой:

float *array = new float[100];

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

if (array != NULL) cout << "Память выделена успешно" << endl;
else cout << "new не может выделить память" << endl;

Предыдущая программа использовала оператор new для выделения 100 байт памяти. Поскольку эта программа "жестко закодирована" на объем требуемой памяти, возможно, вам потребуется ее редактировать и перекомпилировать, если возникнет необходимость, чтобы программа выделила меньше или больше памяти. Как уже кратко обсуждалось, одна из причин для динамического распределения памяти состоит в том, чтобы избавиться от необходимости редактировать и перекомпилировать программу при изменении требований к объему памяти. Следующая программа ASK_MEM.CPP запрашивает у пользователя количество байт памяти, которое необходимо выделить, и затем распределяет память, используя оператор new:

#include

void main(void)

{
int size;
char *pointer;
cout << "Введите размер массива, до 30000: ";
cin >> size;
if (size <= 30000)

{
pointer = new char[size];
if (pointer != NULL) cout << "Память выделена успешно" << endl;
else cout << "Невозможно выделить память" << endl;
}
}

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

Следующая программа NOMEMORY.CPP выделяет каждый раз память для 10000 символов до тех пор, пока оператор new не сможет больше выделить память из свободной памяти. Другими словами, эта программа удерживает выделенную память, пока не использует всю доступную свободную память. Если программа успешно выделяет память, она извещает об этом сообщением. Если память больше не может быть выделена, программа выводит сообщение об ошибке и завершается:

#include

void main(void)

{
char * pointer;
do

{
pointer = new char[10000];
if (pointer != NULL) cout << "Выделено 10000 байт" << endl;
else cout << "Больше нет памяти" << endl;
} while (pointer 1= NULL);
}

Замечание: Если выработаете в среде MS-DOS, то, возможно, будете удивлены тем, что свободная память исчерпается после того, как программа выделит 64 Кбайт, Большинство работающих в MS-DOS компиляторов C++ по умолчанию используют малую модель памяти, которая обеспечивает только 64 К6aйm свободной памяти. Аналогично, если вы используете среду MS-DOS, то наибольшая область памяти, к которой могут обратиться ваши программы, может быть ограничена 64Кбайт.

О свободной памяти

Каждый раз при запуске вашей программы компилятор C++ устанавливает отдельную область неиспользуемой памяти, которая называется свободной памятью. Используя оператор new, ваша программа может выделить память из этой свободной памяти во время выполнения. Используя свободную память для распределения требуемой памяти, ваши программы не стеснены фиксированными размерами массивов. Размер свободной памяти может изменяться в зависимости от вашей операционной системы и модели памяти компилятора. Если увеличивается количество динамической памяти, требуемой вашими программами, вам необходимо убедиться, что вас не сдерживают ограничения свободной памяти вашей системы.

ОСВОБОЖДЕНИЕ ПАМЯТИ, ЕСЛИ ОНА БОЛЬШЕ НЕ НУЖНА

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

delete pointer;

Следующая программа DEL_MEM.CPP использует оператор delete для освобождения выделенной с помощью оператора new памяти:

#include

#include

void main(void)

{
char *pointer = new char[100];
strcpy(pointer, "Учимся программировать на языке C++");
cout << pointer << endl;
delete pointer;
}

По умолчанию, если ваша программа не освобождает выделенную ей память до своего завершения, операционная система автоматически освобождает эту память после завершения программы. Однако если ваша программа использует оператор delete для освобождения памяти по мере того, как она (память) становится ненужной, то эта память вновь становится доступной для других целей (возможно, для вашей программы, которая опять будет использовать оператор new, или для операционной системы).
Второй пример

Следующая программа ALLOCARR.CPP выделяет память для хранения массива из 1000 целочисленных значений. Затем она заносит в массив значения от 1 до 1000, выводя их на экран. Потом программа освобождает эту память и распределяет память для массива из 2000 значений с плавающей точкой, занося в массив значения от 1.0 до 2000.0:

#include

void main(void)

{
int *int_array = new int[1000];
float *float_array;
int i;
if (int_array 1= NULL)

{
for (i = 0; i < 1000; i++) int_array[i] = i + 1;
for (i = 0; i < 1000; i++) cout << int_array[i] << ' ';
delete int_array;
}
float_array = new float[2000];
if (float_array != NULL)

{
for (i = 0; i < 2000; i++) float_array[i] = (i + 1) • 1.0;
for (i = 0; i < 2000; i++) cout << float_array[i] << ' ' ;
delete float_array;
}
}

Как правило, ваши программы должны освобождать память с помощью оператора delete по мере того, как память становится программам не нужна.
ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

Из этого урока вы узнали, что ваши программы могут распределять память динамически во время выполнения из неиспользуемой памяти, называемой свободной памятью, используя для этих целей оператор new. Выделяя подобным образом память динамически, программы могут удовлетворять ваши изменяющиеся запросы без редактирования и перекомпиляции самой программы. Из урока 32 вы узнаете, как управлять распределением свободной памяти, и что делают операторы new, если они не могут удовлетворить запрос на распределение памяти. Прежде чем перейти к уроку 32, убедитесь, что вы изучили следующее:

1. Способность выделять память динамически во время выполнения снимает с ваших программ зависимость от фиксированных размеров массивов.
2. Если оператор new успешно выделяет требуемую вашей программой память, он возвращает указатель на начало области этой памяти.
3. Если оператор new не может выделить требуемую вашей программой память, он возвращает NULL-указатель, который содержит значение 0.
4. Каждый раз, когда ваши программы распределяют память динамически с использованием оператора new, они должны проверять значение возвращаемого оператором new указателя, чтобы определить, не равен ли он NULL, что указывает на невозможность выделения памяти.
5. Используя указатель на массив, ваши программы могут обращаться к памяти, выделенной с помощью оператора new.
6. Оператор new выделяет память из блока неиспользуемой памяти, называемой свободной памятью.
7. В зависимости от вашей операционной системы и модели памяти компилятора размер свободной памяти может быть различным. В среде MS-DOS свободная память может быть ограничена 64 Кбайт.
8. Если вашей программе больше не нужна выделенная память, она должна освободить ее (вернуть в свободную память), используя для этого оператор delete.

Предыдущий вопрос | Содержание | Следующий вопрос

 

Внимание!

1. Все книги являются собственностью их авторов.
2. Предназначены для частного просмотра.
3.Любое коммерческое использование категорически запрещено.

 

 


In-Server & Artificial Intelligence

Контакты

317197170

support[@]allk.ru

 

Ссылки

Art