Удаление нулевого указателя не приводит ни к каким последствиям (так как нулевой указатель не ссылается ни на один объект), поэтому эта операция безвредна. Рассмотрим пример.
int* p = 0;
delete p; // отлично: никаких действий не нужно
delete p; // тоже хорошо (по-прежнему ничего делать не нужно)
Зачем возиться с освобождением памяти? Разве компилятор сам не может понять, когда память нам больше не нужна, и освободить ее без вмешательства человека? Может. Такой механизм называется
17.5. Деструкторы
Теперь мы знаем, как хранить элементы в векторе. Мы просто выделим достаточное количество свободной памяти и будем обращаться к ней с помощью указателя.
// очень упрощенный вектор, содержащий числа типа double
class vector {
int sz; // размер
double* elem; // указатель на элементы
public:
vector(int s) // конструктор
:sz(s), // инициализация члена sz
elem(new double[s]) // инициализация члена elem
{
for (int i=0; i
// элементов
}
int size() const { return sz; } // текущий размер
// ...
};
Итак, член sz
хранит количество элементов. Мы инициализируем его в конструкторе, а пользователь класса vector
может выяснить количество элементов, вызвав функцию size()
. Память для элементов выделяется в конструкторе с помощью оператора new
, а указатель, возвращенный оператором new
, хранится в члене elem
.
Обратите внимание на то, что мы инициализируем элементы их значением по умолчанию (0.0
). Класс vector
из стандартной библиотеки делает именно так, поэтому мы решили сделать так же с самого начала.
К сожалению, наш примитивный класс vector
допускает утечку памяти. В конструкторе он выделяет память для элементов с помощью оператора new
. Следуя правилу, сформулированному в разделе 17.4, мы должны освободить эту память с помощью оператора delete
. Рассмотрим пример.
void f(int n)
{
vector v(n); // выделяем память для n чисел типа double
// ...
}
После выхода из функции f()
элементы вектора v
, созданные в свободной памяти, не удаляются. Мы могли бы определить функцию clean_up()
— член класса vector
и вызвать ее следующим образом:
void f2(int n)
{
vector v(n); // определяем вектор,
// выделяющий память для других n переменных
// типа int
// ...используем вектор v...
v.clean_up(); // функция clean_up() удаляет член elem
}