2016-11-20 2 views
-2

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

int* arr = new int[30]; 
int* newArr = new int[30]; 
arr[15] = 5; 
newArr[15] = 9; 
arr = newArr; 
delete[] newArr; 

Последняя строка освободит newArr, тем самым освободив обр. Но что случилось с блоком памяти, который содержал 5? Это теперь утечка памяти, к которой никогда нельзя получить доступ? Если да, то как я должен позаботиться о том, чтобы эта память никогда не могла просочиться, и в то же время успешно переназначить исходный массив?

+1

_ "тем самым также освобождая arr" _ Huh ?? –

+0

@ πάνταῥεῖ arr и newArr указывают на одно и то же, так что я ошибаюсь, говоря, что я освобождаю их обоих с помощью 'delete [] newArr'? –

+0

Освобождение от одной и той же вещи? Что это значит? – juanchopanza

ответ

0

Последняя строка освободит newArr, тем самым освобождая arr

free(p) С, вы не освободив p, но блок памяти, на который указывает p.


С arr = newArr, вы по существу «потеряли след» динамически выделенный блок памяти, который был первоначально указываемой arr, что означает, что вы больше не можете освободить его на более позднем этапе выполнения вашей программы , следовательно, утечка памяти становится неизбежной.

1
int* arr = new int[30]; 
int* newArr = new int[30]; 
arr[15] = 5; 
newArr[15] = 9; 
arr = newArr; 
delete[] newArr; 

Последняя строка освободит newArr, тем самым освободив обр.

Не совсем. newArr и arr - это просто имена, которые указывают на блоки памяти. Вы действительно не «бесплатно newArr», вы освобождаете блок памяти, на который он указывает сейчас. Который в тот момент оказывается тем же самым блоком, который на данный момент указывает arr.

Но что случилось с блоком памяти, который содержал 5?

Он по-прежнему отмечен как использованный, но ничто в вашей программе никогда не сможет указать на него снова. Единственный указатель, который вам когда-либо был, был arr, но затем вы назначили arr чему-то еще.

Неужели это утечка памяти, к которой никогда нельзя получить доступ?

Точно.

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

Забудьте обо всем этом динамическом массиве бессмысленности и используйте std::vector.

std::vector<int> arr(30); 
std::vector<int> newArr(30); 
arr[15] = 5; 
newArr[15] = 9; 
arr = newArr; 
+0

«Забудьте об этом бессмысленном массиве и используйте« std :: vector ». Забавно, что вы упомянули об этом, потому что я на самом деле столкнулся с этой проблемой, пытаясь реализовать векторный класс самостоятельно на C++ для практики, и он побеждает цель используйте std :: vector в вашей собственной реализации вектора. Указатель использовался, потому что базовый массив в векторной реализации в какой-то момент должен быть изменен, но я не совсем уверен, как это сделать без создания утечек памяти ... –

+0

@CoffeeMaker: 'std :: vector''s реализация не использует 'new []', а размещение new (что позволяет ему заранее резервировать память умным способом). Не то чтобы это вам очень помогает. Вы должны научиться тому, как реализовать свой оператор присваивания, чтобы освободить прежнюю память. Подсказка: освободите память в своем деструкторе, найдите «Правило трех» и выполните назначение с помощью идиомы «Копировать и своп». –

Смежные вопросы