C++: Указатели и объем

int* test( )
{
    int a = 5;
    int* b = &a;
    return b;
}

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

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

5
задан oh boy 30 April 2010 в 16:32
поделиться

4 ответа

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

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

7
ответ дан 18 December 2019 в 13:12
поделиться

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

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

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

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

5
ответ дан 18 December 2019 в 13:12
поделиться

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

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

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

0
ответ дан 18 December 2019 в 13:12
поделиться

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

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

2
ответ дан 18 December 2019 в 13:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: