C ++: указатели и область видимости - PullRequest
5 голосов
/ 30 апреля 2010
int* test( )
{
    int a = 5;
    int* b = &a;
    return b;
}

Будет ли результат test равен bad pointer? Насколько я знаю, a следует удалить, и тогда b станет испорченным указателем, верно?

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

Ответы [ 4 ]

7 голосов
/ 30 апреля 2010

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

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

5 голосов
/ 30 апреля 2010

Да, это указатель на то, что больше не существует, локальная переменная называется. Является ли int, массив, экземпляр класса не имеет значения. А в с ++ нет сборки мусора.

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

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

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

2 голосов
/ 30 апреля 2010

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

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

0 голосов
/ 30 апреля 2010

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

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

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

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