Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Неправильно ли использовать удаление вне области видимости, как это?

Автор вопроса: user3514491Ответов: 2
int* func()
{
   int* i=new int[3];
   return i;
}

void funcc()
{
   int* tmp=func();
   //delete allocated memory after use
   delete[] tmp;
}

Я считаю, что компилятор при компиляции funcc не может знать, что нужно удалить 3 int, например, если func находится в другом файле.

  • Я бы подумал, что delete чаще всего будет использоваться вне области видимости в том смысле, что вы не отпускаете указатель в той же области, в которой вы его выделяете. Право собственности на указатель определяется разработчиком приложения. Точка, в которой он должен быть выпущен, может не совпадать с точкой, в которой он был выделен. Brandon Buck 23.04.2014

c++new-operator

Ответы

Ответ 1 · рейтинг 6 · Philipp

Это описано в Часто задаваемые вопросы по C++ lite:

[16.14] После того, как p = new Fred[n], как компилятор узнает, что во время delete[] p нужно уничтожить n объектов?

Краткий ответ: Магия.

Длинный ответ: система времени выполнения хранит количество объектов n где-то, откуда его можно получить, если вы знаете только указатель, p. Есть два популярных метода, которые делают это. Оба эти метода используются компиляторами коммерческого уровня, оба имеют компромиссы, и ни один из них не идеален. Эти методы:

  • Перераспределите массив и поместите n слева от первого объекта Fred.
  • Используйте ассоциативный массив с p в качестве ключа и n в качестве значения.

Ответ 2 · рейтинг 6 · Mike Seymour

Именно так предполагается использовать delete, и это нормально. Размер массива хранится где-то за кулисами, так что delete[] будет поступать правильно, где бы это ни происходило.

Однако манипулирование указателями, подобное этому, чревато ошибками: легко потерять указатель перед удалением массива или логика становится настолько сложной, что вы в конечном итоге удаляете один и тот же массив дважды. Вам лучше использовать класс для управления массивом для вас:

#include <vector>

std::vector<int> func() {
    return std::vector<int>(3);
}

void funcc() {
    auto tmp = func();
    // no need to do anything - the vector frees its memory automatically
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы