Разделы презентаций


Управление памятью

Содержание

Операции new и deleteОбъект, размер в памяти которого заранее не известен, можно создавать в куче (или стеке)Операция new создает объект в кучевыделяет памятьвызывает конструкторвозвращает указатель на объект (или NULL, если нет

Слайды и текст этой презентации

Слайд 1Тема: Управление памятью
Распределение памяти
Создание и уничтожение объектов
Инкапсуляция управления памятью

Тема: Управление памятьюРаспределение памятиСоздание и уничтожение объектовИнкапсуляция управления памятью

Слайд 2Операции new и delete
Объект, размер в памяти которого заранее не

известен, можно создавать в куче (или стеке)
Операция new создает объект

в куче
выделяет память
вызывает конструктор
возвращает указатель на объект (или NULL, если нет свободной памяти)
Объект существует до его явного уничтожения операцией delete
Операция delete уничтожает объект
вызывает деструктор
освобождает память
Операции new и deleteОбъект, размер в памяти которого заранее не известен, можно создавать в куче (или стеке)Операция

Слайд 3Распределение памяти: время «Ч»

int i = 34;

int* func( ) {
int*

ptr;
ptr = new int;
*ptr = 75;
return ptr;
}

void func2( ) {
int*

ptr2;
ptr2 = func();
delete ptr2;
}

Распределение памяти: время «Ч»int i = 34;int* func( ) {	int* ptr;	ptr = new int;	*ptr = 75;	return ptr;}void

Слайд 4Использование new и delete

#include “mystring.h”
void main( int argc, char* argv[

] ) {
// Динамическое размещение
// объекта типа String
String* ptr1 ;
ptr1

= new String ;
if( ptr1 == 0 ) exit(1) ;
*ptr1 = “Hello, world”;
(*ptr1 + “\n”).print();
// Динамическое размещение и
// инициализация объекта String
String* ptr2 ;
ptr2 = new String(“Hello, world”) ;
if( ptr2 == 0 ) exit(2) ;
(*ptr2 + “\n”).print();


// Динамическое размещение
// массива объектов типа String
String* ptr3 ;
ptr3 = new String[argc] ;
if( ptr3 == 0 ) exit(1) ;
ptr3[argc-1] = “Hello, world”;
(ptr3[argc-1] + “\n”).print();
// Уничтожение объектов
delete ptr1 ;
delete ptr2 ;
delete [argc] ptr3 ;
// или delete [] ptr3 ;
}

Использование new и delete#include “mystring.h”void main( int argc, char* argv[ ] ) {	// Динамическое размещение	// объекта типа

Слайд 5Улучшение класса String
Реализация строки с использованием динамически выделяемой памяти
может быть

скрыта в классе
снимаются ограничения на длину строки
рационально расходуется память
Если принципы

ООП соблюдены, то пользователю не потребуется вносить изменения в программу (но потребуется ее перекомпилировать)
Разработчику потребуется проверить, перепрограммировать и заново отладить методы класса и функции-друзья.
Улучшение класса StringРеализация строки с использованием динамически выделяемой памятиможет быть скрыта в классеснимаются ограничения на длину строкирационально

Слайд 6Пересмотренный класс String
class String {
public:
String() ;
String( const char* ) ;
String(

const String& ) ;
~String() ;
operator const char*( ) const;
String& operator=

( const String& );
int length( ) const ;
int read( ); // чтение из stdin
void print( ) const; // вывод в stdout
char& operator[ ] ( int );
const char& operator[ ] ( int ) const;
String substring (int start, int len) const;
friend String operator+ (const String&, const String& );
private:
// text указывает на область динамической памяти,
// всегда завершающуюся терминальным байтом
char* text ;
};
Пересмотренный класс Stringclass String {	public:		String() ;		String( const char* ) ;		String( const String& ) ;		~String() ;		operator const char*(

Слайд 7Выделение памяти под объект (старая реализация)

Выделение памяти под объект (старая реализация)

Слайд 8Выделение памяти под объект (новая реализация)
String* s_ptr = new String(“Hello”);

*s_ptr
s_ptr->text








s_ptr

адрес

стек
куча

адрес
Hello\0

Выделение памяти под объект (новая реализация)String* s_ptr = new String(“Hello”);*s_ptr s_ptr->texts_ptr адресстеккуча адрес Hello\0

Слайд 9Создание объектов типа String
String s ;
// или
String* s_ptr ;
s_ptr

= new String ;
перед конструктором
выделена память под указатель text

после

конструктора

text

адрес

text

‘\0’

String::String() {
if( !(text = new char) )
error_msg(“Нет памяти для пустой строки”) ;
*text = ‘\0’ ;
}

Синтаксис

Создание объектов типа StringString s ;// или String* s_ptr ;s_ptr = new String ;перед конструкторомвыделена память под

Слайд 10Инициализация объектов типа String
String s = “Hello”;
// или
String* s_ptr

;
s_ptr = new String(“Hello”) ;
выделена память под указатель text
перед конструктором


после конструктора

text

адрес

text

“Hello\0”

String::String( const char* s ) {
if( !(text = new char[strlen(s)+1]) )
error_msg(“Нет памяти для строки \n” ) ;
strcpy( text , s) ;
}

Синтаксис

Инициализация объектов типа StringString s = “Hello”;// или String* s_ptr ;s_ptr = new String(“Hello”) ;выделена память под

Слайд 11Копирование объектов типа String
String s = t ;
// или
String*

s_ptr ;
s_ptr = new String(t) ;
выделена память под указатель text
перед

конструктором


после конструктора

text

адрес

text

“Hello\0”

String::String( const String& s ) {
if( !(text = new char[s.length()+1]) )
error_msg(“Нет памяти для строки \n” ) ;
strcpy( text , s.text ) ;
}

Синтаксис

Копирование объектов типа StringString s = t ;// или String* s_ptr ;s_ptr = new String(t) ;выделена память

Слайд 12Уничтожение объектов типа String
String* s_ptr ;
s_ptr = new String ;
//

…………
delete s_ptr ;
// или s уничтожается
// автоматически
перед деструктором
память занята под

указатель text


после деструктора

text

адрес

text

“Hello\0”


String::~String( ) { delete text ; }

Синтаксис

Уничтожение объектов типа StringString* s_ptr ;s_ptr = new String ;// …………delete s_ptr ;// или s уничтожается// автоматическиперед

Слайд 13Присваивание объектов типа String

t = s
перед присваиванием

адрес
text
‘\0’
Синтаксис:
t
адрес
text
“Hello\0”
s
после присваивания
адрес
text
t
адрес
text
“Hello\0”
s
“Hello\0”

Присваивание объектов типа String   t = sперед присваиванием адресtext ‘\0’Синтаксис:t адресtext “Hello\0”sпосле присваивания адресtextt адресtext

Слайд 14Операция присваивания объектов типа String

String& String::operator=(const String& s) {

if( this != &s ) { // на случай t=t

delete text ; // освободить старую память
if( !(text = new char[s.length()+1]) )
error_msg(“Нет памяти для строки \n” ) ;
strcpy( text , s.text ) ;
}
return *this ;
}

Операция присваивания объектов типа StringString& String::operator=(const String& s) {  if( this != &s ) {	// на

Слайд 15Конкатенация строк
#include “mystring.h”
#include
#include
String operator+(const String& s1 , const

String& s2 ) {
String both ;
delete

both.text ;
if( !(both.text = new char[s1.length()+s2.length()+1]) )
error_msg(“Нет памяти для строки \n” ) ;
strcpy( both.text , s1.text ) ;
strcat( both.text , s2.text ) ;
return both ;
}
Конкатенация строк#include “mystring.h”#include #include String operator+(const String& s1 , const String& s2 ) {  String both

Слайд 16Использование закрытых методов

inline void String::alloc_and_set(const char* s)
{
if( !(text

= new char[ strlen(s)+1]) )

error_msg(“Нет памяти для строки \n” ) ;
strcpy( text , s ) ;
}

В ряде методов класса приходится выполнять одно и то же действие:
выделить участок динамической памяти
заполнить ее символьной строкой

Использование закрытых методовinline void String::alloc_and_set(const char* s){  if( !(text = new char[ strlen(s)+1]) )

Слайд 17Методы класса String
String::String( ) { alloc_and_set(“”); }
String::String( const String& s

) { alloc_and_set(s.text); }
String::String( const char* s ) { alloc_and_set(

s ); }
String& String::operator=(const String& s) {
if( this != &s ) { // на случай t=t
delete text ; // освободить старую память
alloc_and_set( s.text );
}
return *this ;
}
Методы класса StringString::String( ) { alloc_and_set(“”); }String::String( const String& s ) { alloc_and_set(s.text); }String::String( const char* s

Слайд 18«Приемчики» эффективности
String operator+(const String& s1 , const String& s2

) {
String both ;
delete

both.text ;
if( !(both.text = new char[s1.length()+s2.length()+1]) )
error_msg(“Нет памяти для строки \n” ) ;
strcpy( both.text , s1.text ) ;
strcat( both.text , s2.text ) ;
return both ;
}

Операция конкатенации неэффективна:
создается переменная both (вызов конструктора)
манипуляции с динамической памятью
возврат результата (вызов конструктора)

«Приемчики» эффективности String operator+(const String& s1 , const String& s2 ) {   String both ;

Слайд 19Применим закрытый конструктор
String::String(const char* s1, const char* s2) {

if( !(text = new char[ srtlen(s1) + srtlen(s2)

+ 1]) )
error_msg(“Нет памяти для строки \n” ) ;
strcpy( text , s1 ) ;
strcat( text , s2 ) ;
}
inline String operator+(const String& s1 , const String& s2 )
{
return String( s1.text , s2.text ) ;
}

Применим закрытый конструктор String::String(const char* s1, const char* s2) {   if( !(text = new char[

Слайд 20Закрытые методы класса String
class String {
public:
// методы класса
private:
String(const char*

, const char* );
void alloc_and_set(const char* );
// text указывает

на область динамической
// памяти, всегда завершающуюся
// терминальным байтом
char* text ;
};
Закрытые методы класса Stringclass String {	public:		 // методы класса	private:		String(const char* , const char* ); 		void alloc_and_set(const char*

Слайд 21РЕЗЮМЕ
Классы с динамической памятью
более гибкие и эффективные
более сложные в реализации
Простая

реализация позволяет сосредоточиться на интерфейсе
Изменение реализации не требует изменений программ

пользователей (только перекомпиляция)
Динамические классы требуют нетривиальной реализации
конструкторов
деструктора
операции присваивания
РЕЗЮМЕКлассы с динамической памятьюболее гибкие и эффективныеболее сложные в реализацииПростая реализация позволяет сосредоточиться на интерфейсеИзменение реализации не

Слайд 22Упражнение
Изменить реализацию класса String так, чтобы длина строки определялась целым

полем len, а сама строка была динамическим массивом символов, но

без терминального байта:
class String {
public:
// те же методы класса
private:
int len;
char* text ;
}
УпражнениеИзменить реализацию класса String так, чтобы длина строки определялась целым полем len, а сама строка была динамическим

Слайд 23Лабораторная работа
Создать класс intArray, представляющий массив целых чисел. Класс должен

быть объявлен в файле intarray.h. Код методов поместите в любой

файл (или файлы), по своему усмотрению 
Спецификация класса intArray
Размер массива Int_array должен задаваться при его создании:
intArray ia(10);
Доступ к элементам массива осуществляется с помощью операции []. (Заметим, что для этого не требуется метод operator=() ).
ia[0] = 100; ia[1] = 10;
Программа прерывается, если задается некорректный индекс:
  ia[9] = 17; // все нормально
ia[5000] = 508; // программа прерывается
Лабораторная работаСоздать класс intArray, представляющий массив целых чисел. Класс должен быть объявлен в файле intarray.h. Код методов

Слайд 24Массивы типа intArray могут присваиваться; в этом случае, массив intArray

, находящийся слева, получает размер и все элементы массива intArray

, находящегося справа:
intArray ia2(7);
ia2[0] = -1;
ia2 = ia;
Если массив intArray передается функции по значению, функция получает копию этого массива:
test(ia2);
printf("ia2[9] should still be 17: %d\n", ia2[9]);
// тестом является следующий код:
void test(intArray copy) {
printf("copy[9] should be 17: %d\n", copy[9]);
copy[9] = -1;
printf("copy[9] changed to -1: %d\n", copy[9]);
}
Массивы типа intArray могут присваиваться; в этом случае, массив intArray , находящийся слева, получает размер и все

Обратная связь

Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика