Что-то непонятное с оператором delete - PullRequest
4 голосов
/ 23 сентября 2011

Я новичок в C ++, и у меня есть что-то неясное:

#include <iostream>
using namespace std;

double* foo(void)
{
    double* b = new double[100];
    return b;
}

int main()
{
    double* a = foo();

    delete [] a;
    return 0;
}

Что-то не так с этим кодом? Я имею в виду, правильно ли использовать оператор удаления? Я назначаю указатель b, который указывает на выделенную память в функции foo, для указания на внешний foo, могу ли я освободить память с помощью delete [] a в main? Я понятия не имею, как компилятор вычисляет количество байтов для освобождения при выполнении delete []. Спасибо

Ответы [ 2 ]

5 голосов
/ 23 сентября 2011

Код правильный (хотя обычно он не является частью хорошо написанной современной программы на C ++).

Динамически размещенные массивы хранятся со скрытой информацией об их размере, поэтому delete[] p знает, сколько элементов нужно удалить.


Если вам интересно узнать подробности, вы можете настроить небольшой тестовый класс и воспользоваться преимуществами операторов распределения членов:

struct ArrayMe
{
  static void * operator new[](size_t n) throw(std::bad_alloc)
  {
    void * p = ::operator new[](n);
    std::cout << "new[]ed " << n << " bytes at " << p << "." << std::endl;
    return p;
  }

  static void operator delete[](void * p, std::size_t n) throw()
  {
    std::cout << "delete[]ing " << n << " bytes at " << p << "." << std::endl;
    ::operator delete[](p);
  }

  double q;
};

Теперь скажите:

std::cout << "sizeof(ArrayMe) = " << sizeof(ArrayMe) << std::endl;
ArrayMe * const a = new ArrayMe[10];
delete[] a;
1 голос
/ 23 сентября 2011

Вызовите delete [], чтобы удалить массивы в стиле C, выделенные оператором new []. Delete [] будет знать, сколько байтов было выделено оператором new [].

Вызовите delete для удаления объектов, выделенных оператором new (без скобок). Никогда, никогда не смешивайте их! То есть никогда не вызывайте delete [] для чего-то, выделенного оператором new, и никогда не вызывайте delete для чего-то, выделенного оператором new [].

...