2010-04-30 5 views
5
int* test() 
{ 
    int a = 5; 
    int* b = &a; 
    return b; 
} 

Будет ли результат testbad pointer? Насколько я знаю, a следует удалить, а затем b станет перепутанным указателем, не так ли?C++: Указатели и область применения

Как насчет более сложных вещей, а не указателя int, но то же самое с классом с 20 членами или около того?

+2

Здесь нет мусора. Просто разматывайте стеки. – Tom

ответ

7

Термин для того, что вы возвращаете, является «dangling pointer». a - это локальная переменная, выделенная в стеке, и она больше не доступна, когда она выходит из сферы действия (что совсем не отличается от сбора мусора). Попытка использовать результат вызова test() будет неопределенным поведением.

С другой стороны, если вы не выделяло a на стеке - (int *a = new int(5);), то int *b = a; return b; будет просто отлично, хотя и не так хорошо, как return new int(5). Тем не менее, если результат не будет корректным, результат будет потерян.

+0

Хорошо - и есть ли способ решить это?Чтобы значение сохранялось, я не должен его определять в другом месте? –

+0

Что именно ваша цель? Возвращает указатель на один и тот же объект каждый раз, когда вызывается 'test()'? Например, вы можете вернуть адрес статической переменной. –

5

Да, это указатель на то, что больше не существует, локальная переменная называется a. Независимо от того, является ли int, массив, экземпляр класса не имеет значения. И C++ не содержит сборку мусора.

В этом случае, и во многих других, вы должны, конечно, вернуть копию:

int test() 
{ 
    int a = 5; 
    return a; 
} 

Это верно для классов, а также встроенные типы.

2

Указатель b в этом случае указывает на объект, выделенный из стека. Эта память будет доступна вызывающему процессу, как только эта функция вернется.

Если вам нужно создать объект, который переживет процесс, который его создал, вы должны будете использовать malloc() или new, чтобы получить блок памяти из кучи, и не забудьте free или delete позже.

0

Да, это даст свисающий указатель. Если вы хотите, чтобы значение сохранялось, у вас есть несколько возможностей. Во-первых, поскольку вы, по-видимому, действительно хотите вернуть значение, сделайте именно это - верните значение вместо указателя. Другой - выделить объект, связанный с новым, и вернуть указатель на это динамически выделенное пространство. Это делает удаление объекта ответственностью вызывающего абонента, однако, что может привести к утечке памяти и тому подобное.

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

Если вы не можете этого сделать, вам все равно нужно выяснить, кто «владеет» объектом, и будет нести ответственность за его уничтожение по мере необходимости. Время от времени это трудно подкрепить, и вам нужно что-то вроде указателя с подсчетом ссылок, чтобы отслеживать все. По крайней мере, по моему опыту, они используются гораздо чаще, чем на самом деле. Я писал C++ почти до тех пор, пока кто-либо за пределами AT & T, и пока не нужен shared_ptr. Несколько раз, я думал, что мне это нужно, но в итоге выяснил, что более чистый дизайн устраняет это требование.

+0

Вы можете использовать общие указатели для более старых систем, которые могут делать неожиданные вещи, и которые вы не хотите переделывать, и получаете значительную степень безопасности. Более того, им легче сохранять правильные изменения в течение многих лет. –

+0

@ Давид: Да, совершенно верно - я не хотел подразумевать, что они бесполезны или что-то в этом роде. В то же время я склонен думать о них как о большей помощи, чем о том, как код действительно должен быть написан. Однако нет никаких сомнений в том, что если/когда у вас есть код, который является «кровоточащей» памятью, бандажная помощь может быть чрезвычайно полезной ... –

+0

Они в основном сбор мусора, довольно примитивный и децентрализованный. Они полезны везде, где есть сбор мусора, и для больших реальных систем я предпочел бы зависеть от GC, чем от каждого разработчика, который работал над ним в течение последних десяти лет. –

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