Указатель удаления C ++ выделяется дважды - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь больше узнать об указателях C ++ и освобождении памяти. Допустим, у нас есть следующий фрагмент кода

int main{

  int * A = new int[4];
  int * B = new int[4];
  A = B;

  delete[] A;
  delete[] B;

  return 0;
}

A указывает на новый созданный указатель, тогда как B указывает на другой, так что всего у нас есть два указателя. Теперь произнесение A = B означает, что A и B теперь указывают на один и тот же указатель. Итак, что в этом случае происходит с другим указателем? А как его удалить?

Ответы [ 2 ]

4 голосов
/ 27 мая 2020

Следовательно, что происходит с другим указателем в этом случае?

Он теряется. Вы сбросили последнюю ссылку на массив, на который A указывал (A и B не указывают на указатели. Это указатели, и они указывают на первый элемент массивов, ie int s соответственно).

А как его удалить?

Нельзя. Утечка памяти.

Никогда не используйте необработанные указатели владения. Для динамических массивов c вы можете использовать std::vector, а для других вы можете использовать интеллектуальные указатели. С std::vector ваш код будет:

#include <vector>
int main{
    auto A = std::vector<int>(4);
    auto B = std::vector<int>(4);
    A = B;
}

И для полноты также версия вашего кода без утечек:

void please_dont_do_this() {    
  int * A = new int[4];
  int * B = new int[4];

  delete [] A; // delete the array before the pointer is lost

  A = B;

  delete[] B;  // delete the array only once !    
}

PS: Я знаю, что это представление не очень популярен среди энтузиастов c новичков, которые хотят узнать как можно больше, но имхо самая важная вещь, которую вам нужно знать о необработанных указателях в C ++, это то, что они вам почти никогда не понадобятся (а когда вы думаете, что они вам нужны, то, скорее всего, вы все еще не знаете).

3 голосов
/ 27 мая 2020

Здесь нет ничего особенного в указателях.

int i = 3;
i = 4;

Что случилось с 3? Он ушел, перезаписан i = 4. То же самое и с указателями:

int *p = new int[4];
int *q = new int[4];

p указывает на массив int и q указывает на другой массив int.

p = q;

Старое значение из p пропал, перезаписан p = q. p и q теперь содержат такое же значение указателя , и этот указатель указывает на память, выделенную вторым вызовом new int[4].

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...