Возврат указателя на локальную переменную C++

69
19 февраля 2022, 15:20

Есть два варианта функции. Почему не работает первый - понятно, но почему тогда срабатывает второй вариант?

Первый:

int* f() {
   int b = 10;
   return &b;
}

Второй:

int* f() {
   int b = 10;
   int* a = &b;
   return a;
}
Answer 1

Окей, в вашем вопросе на самом деле несколько вопросов.

Во-первых, ваш код, оба его варианта, очевидно неверен, так как локальные переменные умирают вместе с фреймом стека функции, в которой они определены.

Почему первый вариант не компилируется? Компилятор, очевидно, видит, что вы возвращаете указатель на локальную переменную, и выдаёт ошибку (или, скорее всего, предупреждение).

Почему же тогда второй вариант компилируется? Дело в том, что компилятор не обязан ловить вас за руку каждый раз, когда вы совершаете ошибку. Он не будет рассматривать то, откуда пришли значения во всех переменных, которые вы возвращаете. Если в первом случае он вам помог (потому что это было легко), то во втором он просто решил этого не делать (потому что ему пришлось бы анализировать, откуда пришло значение переменной a). C++ — язык для взрослых, он считает, что программист читал документацию, понимает, что он делает, и компилятор не надоедает программисту излишними предупреждениями.

Да, а почему второй вариант работает? А случайно. У вас в стеке случайно ничего не затёрло переменную, расположенную в ничьей памяти. Вот эту самую ничью память случайно никто не забрал. А мог забрать в любой момент. Просто не делайте так, иначе никаких гарантий нормальной работы программы нет.

Если делать по правилам, программа будет работать. Если делать не по правилам, она может работать, а может и нет.

Answer 2

Повезло. У Вас переменная a хранится в стеке. Вы возвращаете адрес на стек из функции. Что лежит по этому адресу после выхода из функции - неизвестно никому. В данном случае, так совпало, что значение не было затерто

Answer 3

Потому что вы присваивание указателю значение 10.

READ ALSO
Удалит ли деструктор по умолчанию объект, хранящийся в классе в виде ссылки?

Удалит ли деструктор по умолчанию объект, хранящийся в классе в виде ссылки?

Если поле класса хранит ссылку на объект, удалит ли деструктор по умолчанию объект, на который ссылается поле?

68
Как переместить существующий контрол в другое окно

Как переместить существующий контрол в другое окно

Задача - показать контрол в полноэкранном режимеРешил создавать полноэкранное окно перемещать туда контрол, а при закрытии этого окна возвращать...

158
Как подкючить библиотеку [muParser] к Qt?

Как подкючить библиотеку [muParser] к Qt?

Мне нужно будет подключить библиотеку muParser (GitHub) к Qt Creator

101
Не удается подключиться к бд

Не удается подключиться к бд

Пишу в LinuxНеобходимо подключиться к Access бд,но Qtговорит что нет такого драйвера QODBC, хотя в предложенных он имеется

213