пользователей: 30398
предметов: 12406
вопросов: 234839
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ

Динамическая память. Операторы new и delete

 

Справочник по C++

Динамическая память

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

Для этого вам необходимо знать всего два оператора:

  • new - выделение памяти, если выделение памяти не произошло возвращается нулевой указатель;
  • delete - освобождение памяти, не во всех компиляторах после освобождения памяти указателю присваивается 0.

 

#include <iostream>

using namespace std;

 

int main() {

// создание объекта типа int со значением 45

// и сохранение его адреса в указателе obj   

int* obj = new int(45);

 

// освободили память на которую указывал obj

cout<<"*obj="<<*obj<<endl;

delete obj;

 

// елементы массива нельзя инициализировать

// им задается значение по умолчанию

// в случае классов вызывается конструктор по умолчанию

int* array = new int[10];

cout<<"array:";

for(unsigned int i=0; i<10; i++)

     cout<<array[i]<<" ";

cout<<endl;

delete [] array;

 

// для избежания возможных ошибок

// указателю лучше присвоить 0 (при доступе

// к нулевому указателю генерируется системная ошибка,

// а значит ошибка не останется незамеченной)

array=0;

...

}

умные указатели

В С++ нет автоматической сборки мусора. Другими словами, если указатель на выделенную память потерян, то она становится недоступной. Это называется утечкой памяти. Другой крайностью является попытка освободить одну и ту же память более одного раза, что приводит к системной ошибке. Частично или полностью эти проблемы решаются созданием классов, реализующих "умные указатели". Для примера ниже рассмотрены классы из библиотек STL и Boost.

класс auto_ptr

Класс auto_ptr из библиотеки STL имеет следующие ограничения:

  • объектом может владеть только один указатель,
  • объектом не может быть массив,
  • нельзя использовать адресную арифметику.

Единственное предназначение этого класса автоматизировать уничтожение выделенной ранее памяти. Таким образом, данный класс используется, когда время существование выделенного объекта можно ограничить определенным блоком. Аналогичными свойствами обладает и класс scoped_ptr из библиотеки Boost. Но в отличие от auto_ptr для этого класса запрещена передача объекта от одного указателя к другому. Делая код более безопасным, данные классы не наносят ущерб размеру или скорости программы.

 

#include <memory> // здесь объявление шаблона класса auto_ptr

#include <iostream>

using namespace std;

 

// Внутри функции мы выделяем память для объекта типа int

// но не освобождаем ее явно оператором delete.

// Это делается автоматически при выходе из функции,

// когда уничтожаются все локальные переменные.

void func() {

auto_ptr<int> aptr(new int(20));

auto_ptr<int> aptr2;

 

cout<<"*aptr="<<*aptr<<endl;

 

// следующая строка была бы невозможна при использовании scope_ptr

aptr2=aptr; // теперь aptr не владеет никаким объектом       

cout<<"*aptr2="<<*aptr2<<endl;

}

класс shared_ptr

Класс shared_ptr из Boost обладает расширенными возможностями:

  • объект может иметь несколько владельцев;
  • можно указать дополнительный класс, отвечающий за уничтожение объекта.

 

#include <boost/shared_ptr.hpp>

#include <iostream>

using namespace boost;

using namespace std;

 

class A {

shared_ptr<int> ptr;

 

public:

A(shared_ptr<int> pptr) : ptr(pptr) {}

void setValue(int n) {*ptr=n;}

};

 

class B {

shared_ptr<int> ptr;

 

public:

B(shared_ptr<int> pptr) : ptr(pptr) {}

int getValue() const {return *ptr; }

};

 

 

int main() {

shared_ptr<int> ptr(new int(45));

A a(ptr);

B b(ptr);

cout<<"b.getValue()="<<b.getValue()<<endl; 

 

a.setValue(50);

cout<<"now b.getValue()="<<b.getValue()<<endl;      

}

new/delete и классы

Оператор new можно перегрузить для новых классов, а оператор delete для классов автоматически вызывает деструктор.

альтернативы new/delete

Как альтернативой можно воспользоваться С функциями (объявлены в stdlib.h) как malloc и free. Эти функции нельзя смешивать с операторами динамической памяти, то есть нельзя выделить память оператором new и освободить ее функцией free или наоборот.

Также не следует забывать системные возможности управления памятью, например в Windows API есть функции для управления кучей (HeapCreate, HeapAlloc, HeapFree,...) и виртуальной памятью (VirtualAlloc, VirtualFree,...).


27.12.2014; 12:01
хиты: 114
рейтинг:0
Точные науки
информатика
Языки программирования
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2024. All Rights Reserved. помощь