2013-07-03 3 views
0

У меня вопрос простой. Если у меня есть такой код:О существовании указателей

void Holder::Add() 
{ 
    Dish * obj = new Dish(this->screen_width, this->screen_height); 
    this->dish_array.push_back(obj); 
} 

где dish_array объявлен как так:

vector <Dish*> dish_array; 

будет объект, который «* OBJ» указатель указывает на «существование» вне этой функции?

+0

Пожалуйста, не храните необработанные указатели в контейнерах, если вы * абсолютно * не можете избежать этого (что крайне редко), это кошмар обслуживания и большой источник ошибок/утечек. Предпочитайте контейнеры, в которых хранятся либо простые объекты ('vector '), либо, по крайней мере, интеллектуальные указатели ('vector >' или 'vector >'). В качестве примера к тому, что я только что сказал: ваши две строки кода ('new/push_back') могут течь из памяти, поскольку они не являются безопасными для исключений. И это только верхушка айсберга. – syam

+0

@JapeCorbel Я забыл сказать, славное название :) – feralin

ответ

1

Да, конечно. Однако существует два способа определения «существует»:

1) Можете ли вы ссылаться/использовать его вне функции? В этом случае вы можете, потому что ваше значение obj было помещено в переменную dish_array, в которой теперь хранится ссылка на созданный объект.

2) Сохранен ли объект в памяти? В этом случае снова да. Вы никогда не освобождаете объект. Однако, если у вас никогда не было линии this->dish_array.push_back(obj), тогда объект все равно будет в памяти, но вы не сможете ссылаться на него. Это будет утечка памяти .

0

Да. Это побочный эффект new, который выделяется в свободном магазине и поэтому требует применения ручной очистки.

+0

Не совсем побочный эффект. Это предполагаемое поведение, и это, в некоторых случаях, одно из преимуществ «новых» над переменными стека. – paul

+2

Это, безусловно, предполагаемое поведение, но все же является побочным эффектом, поскольку он изменяет состояние программы. Говорят, что функция, которая изменяет состояние программы, имеет побочные эффекты, тогда как чистая функция (без участия государства) не работает. То есть повторный вызов функции не будет повторять одно и то же, несмотря на кажущееся обратное. В этом случае повторный вызов 'new' не приведет к повторному созданию * такого же * объекта (по понятным причинам). – user268396

+0

Извините, у меня были нежелательные побочные эффекты – paul

0

Да. Вы специально запрашиваете с ключевым словом new, что ваш новый экземпляр Dish будет храниться в живых (а не мусор) даже после возвращения Holder::Add. Он останется на куче, пока вы не освободите свою память с помощью delete. Не забудьте сделать это в какой-то момент, потому что в противном случае у вас будет утечка памяти!

0

Да - вызов new возвращает указатель на выделенную память. Вы сохраняете копию этого указателя в своем vector. Выделенная память будет сохраняться до тех пор, пока вы не будете активно вызывать удаление указателя. Чтобы избежать утечки памяти в вашем коде, вам нужно будет перебирать указатели в вашем векторе и удалять на них, прежде чем ваш вектор выйдет из области действия (где бы это ни было). Если, конечно, вы не стираете их в какой-то другой момент и не назовете удалить их в этот момент. Когда вектор уничтожается, все предметы в векторе также уничтожаются - в этом случае у вас есть только указатели, и даже если указатель будет уничтожен, память, на которую они указывают, не освобождается, пока вы не вызываете delete на этом указателе.

0

У C++ нет никакой мусорной коллекции. Любая память, выделенная в куче с использованием malloc или new, будет существовать до тех пор, пока не будет выпущена вручную, используя free или delete. Так да.

0

Да. Вектор в вашем примере кода совершенно не имеет отношения к вашему вопросу. Все, что имеет значение, - это ключевое слово new. Объекты, которые вы выделяете с new, остаются в памяти до 1) вы delete указатель или 2) ваша программа заканчивается, и ОС восстанавливает вашу память. Если ваш вектор выходит из области видимости и все указатели исчезают, объекты, на которые они указывают на STILL, существуют и теперь просочились.

Каждый new должен иметь соответствующий delete или вы должны поместить указатель, который вы получаете, в то, что позаботится об этом для вас (например, shared_ptr).

0

Да, неназванный объект типа Dish, который вы создали с помощью new, будет продолжать существовать вне функции.

Однако это не имеет ничего общего с «существованием указателей», о котором вы указали в названии вашего вопроса. Неименованный объект имеет тип Dish. Это не указатель. Он не имеет никакого отношения к вашему указателю obj.

Указатель obj исчезнет после выхода функции, в то время как объект без названия Dish, к которому он привык, будет отображаться. Вы несете ответственность за то, чтобы значение указателя obj хранилось где-то до obj. Таким образом, вы можете продолжать оценивать этот неназванный объект Dish, который вы создали с помощью new.

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