Я очень осторожно отношусь к утечкам памяти, поэтому решил проверить это. В следующем примере будет ли утечка памяти? Мой инстинкт говорит «да».

class Handler        // Class definition
{public:
  ~Handler();
  int* ptrToInts;    
};

Handler::~Handler()  // Class destructor
{
  delete[] ptrToInts; 
}

Handler handler;     // Global object


void aFunction()
{
    handler.ptrToInts = new int[20];
}


int main()
{
  bool quit = false;

  while(!quit)
    {
      aFunction(); 
    }

  return 0;
}

Будет ли ptrToInts создавать 20 отдельных новых целых чисел в отдельной памяти в каждое время?

Кроме того, еще один вопрос: если бы не деструктор, была бы освобождена динамически выделяемая память? Видя, как будто время жизни класса - это продолжительность программы, будет ли она очищать всю «новую» память?

Изменить: спасибо за ответы. Причина, по которой я спрашиваю об этом, заключается в том, что я пытаюсь обойтись без вызова new и delete каждый раз, когда WndProc вызывается для необработанного ввода, в основном, как MSDN говорит вам это делать. Кажется очень неэффективным.

-2
Zebrafish 29 Апр 2016 в 22:14

4 ответа

Лучший ответ

Как только вы повторно назначаете указатель без использования delete[] для освобождения выделенной памяти в куче, вы создаете утечку памяти. Это произойдет, если вы зациклите свой aFunction(), поскольку он повторно назначает указатель при каждом вызове.

Что касается вашего второго вопроса, ваш деструктор будет только delete[] последний массив, назначенный указателю.

7
Stephen 29 Апр 2016 в 19:17

Конечно есть утечка памяти. Вы распределяете ints в

void aFunction()
{
    handler.ptrToInts = new int[20];
}

Не освобождая сначала старые целые числа, например

void aFunction()
{
    delete [] handler.ptrToInts;
    handler.ptrToInts = new int[20];
}

Сделал бы.

Вызов aFunction() приведет к "бесконечному" распределению памяти. И ваш деструктор, который освобождает только последние выделенные целые числа, никогда не вызывается.

Почему ваш обработчик не управляет собственной памятью?

Это очень плохая практика - выделять память вне вашего объекта и освобождать ее внутри или наоборот.

Почему бы не реализовать класс Handler таким образом:

class Handler
{
public:
  Handler();
  ~Handler();
  void aMethod();
private:
  int* ptrToInts;    
};

Handler::Handler() {
  handler.ptrToInts = new int[20];
}

Handler::~Handler() {
  delete[] ptrToInts; 
}

void Handler::aMethod() {
  delete[] ptrToInts; 
  handler.ptrToInts = new int[20];
}

int main() {
  bool quit = false;
  Handler handler;

  while(!quit) {
    handler.aMethod(); 
  }
}
1
cwschmidt 29 Апр 2016 в 19:39

Да, происходит утечка памяти, когда вы вызываете функцию более одного раза, без явного освобождения handler.ptrToInts после каждого вызова;

void aFunction()
{
    handler.ptrToInts = new int[20];
}

//-----somewhere we see the caller

while(!quit)
    {
      aFunction(); 
    }

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

См. Как вы обнаруживаете / избежать утечки памяти в вашем (неуправляемом) коде?

2
Community 23 Май 2017 в 10:28

Только delete[] освобождает память, выделенную new. И каждый раз, когда вы используете new, вам понадобится delete.

Что касается другого вопроса, то на основе документации :

MyClass * p1 = new MyClass[5]; // allocates and constructs five objects

2
Khalil Khalaf 29 Апр 2016 в 19:16