Форум программистов, компьютерный форум CyberForum.ru

Возвращение ссылки на локальную переменную - C++

Восстановить пароль Регистрация
 
Gwini
10 / 10 / 3
Регистрация: 08.03.2014
Сообщений: 70
02.08.2014, 05:12     Возвращение ссылки на локальную переменную #1
Заметил недавно одну интересную вещь. Как вообще работает такой код? Причем коректно.
C++
1
2
3
4
5
6
7
8
9
10
11
int& func();
int main()
{
    cout << func();
}
 
int& func()
{
    int a = 99;
    return a;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.08.2014, 05:12     Возвращение ссылки на локальную переменную
Посмотрите здесь:

Механизм возврата ссылки на переменную C++
C++ Возвращение ссылки или указателя на закрытый элемент класса.
Записать день в переменную d,месяц в переменную m, год в переменную y C++
Ошибка E2363 Попытка возвратить локальную переменную C++
C++ Возвращение ссылки на указатель использование её как левостороннего значения
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
CyberSolver
 Аватар для CyberSolver
101 / 74 / 17
Регистрация: 23.07.2014
Сообщений: 686
Записей в блоге: 1
02.08.2014, 05:18     Возвращение ссылки на локальную переменную #2
Gwini, не очень-то корректно.
Gwini
10 / 10 / 3
Регистрация: 08.03.2014
Сообщений: 70
02.08.2014, 05:21  [ТС]     Возвращение ссылки на локальную переменную #3
Цитата Сообщение от CyberSolver Посмотреть сообщение
Gwini, не очень-то корректно.
vs выводит 99
CyberSolver
 Аватар для CyberSolver
101 / 74 / 17
Регистрация: 23.07.2014
Сообщений: 686
Записей в блоге: 1
02.08.2014, 05:26     Возвращение ссылки на локальную переменную #4
Gwini, а как вы думаете, что будет с локальной переменной по выходу из функции?
Gwini
10 / 10 / 3
Регистрация: 08.03.2014
Сообщений: 70
02.08.2014, 05:31  [ТС]     Возвращение ссылки на локальную переменную #5
Цитата Сообщение от CyberSolver Посмотреть сообщение
Gwini, а как вы думаете, что будет с локальной переменной по выходу из функции?
Ну должна удалиться, но она существует не в main() и после завершения func() ccылатся уже не на что. Я просто читал что такого делать нельзя, а тут на тебе...
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
02.08.2014, 06:25     Возвращение ссылки на локальную переменную #6
Цитата Сообщение от Gwini Посмотреть сообщение
vs выводит 99
Просто так звёзды совпали, это ничего не значит.
Бендерродригез
Сгибальщик
 Аватар для Бендерродригез
42 / 42 / 3
Регистрация: 18.05.2013
Сообщений: 220
Завершенные тесты: 1
02.08.2014, 07:14     Возвращение ссылки на локальную переменную #7
Цитата Сообщение от gray_fox Посмотреть сообщение
Просто так звёзды совпали, это ничего не значит.
Или cout внезапно принимает &&.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
02.08.2014, 07:24     Возвращение ссылки на локальную переменную #8
Цитата Сообщение от Бендерродригез Посмотреть сообщение
Или cout внезапно принимает &&.
Возвращаемый тип lvalue же, ссылка на rvalue тут вообще не при чём.
Andrej
И целого heap'а мало
 Аватар для Andrej
93 / 54 / 9
Регистрация: 31.07.2014
Сообщений: 293
02.08.2014, 07:57     Возвращение ссылки на локальную переменную #9
Код топик стартера после clanga тоже сработал, хотя, тот упорно жалуется на reference to stack memory.
А вот так сломало:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
int& func();
 
int main()
{
    int& a = (func() = 5);
    int& b = (func() = 3);
    int& c = (func() = 1);
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    std::cout << c << std::endl;
};
 
int&
func()
{
    int a = 99;
    return a;
};
Выводит 1, мусор, мусор.
edit:
Хотя, можно и проще стэк затереть.
__SOKOL__
3 / 3 / 0
Регистрация: 29.06.2013
Сообщений: 107
02.08.2014, 09:28     Возвращение ссылки на локальную переменную #10
Вот так можешь увидеть адрес своей переменной из функции.
Функция возвращает ссылку, и работает правильно выводя 99, а не адрес, ведь в выводе ты не поставил знак амперсанда перед вызовом функции.

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
 
int& func();
 
int main()
{
    cout << &func() << endl;
    return 0;
}
 
int& func()
{
    int a = 5;
    return a;
}


Но так делать не рекомендуется:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
 
int& func();
 
int main()
{
    int &b = func();
    cout << &b << endl;
    cout << b << endl;
    return 0;
}
 
int& func()
{
    int a = 5;
    return a;
}

Так будет потеря данных.
Адрес ты примешь, но значение этого адреса изменится, так как переменная локальная
и её значение удаляется после выхода из функции. У меня вместо 5 выводит 100.

Потерю данных можно избежать если использовать статические переменные или указатели,
но вспомним основы: статические переменные хранятся в памяти до завершения приложения,
а с указателями нужно быть внимательным и не забывать очищать память, или приложение
за час и больше работы может занять 1 и больше Гб ОЗУ.

Пример с указателем:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
 
int& func();
 
int main()
{
    int* b = &func();
    cout << b << endl;
    cout << *b << endl;
    delete b;
    
    return 0;
}
 
int& func()
{
    int *a = new int;
    *a = 5;
    return *a;
}

Вообще указатели это очень классная штука, учись работать с ними.
CyberSolver
 Аватар для CyberSolver
101 / 74 / 17
Регистрация: 23.07.2014
Сообщений: 686
Записей в блоге: 1
02.08.2014, 09:37     Возвращение ссылки на локальную переменную #11
__SOKOL__, ну вы и насоветовали. Выделить в динамике int, чтобы он не потерялся? В Джаве такое будете проделывать, а здесь, если забыть delete (а по закону Мерфи он будет забыт),
Цитата Сообщение от __SOKOL__ Посмотреть сообщение
приложение
за час и больше работы может занять 1 и больше Гб ОЗУ.
__SOKOL__
3 / 3 / 0
Регистрация: 29.06.2013
Сообщений: 107
02.08.2014, 11:06     Возвращение ссылки на локальную переменную #12
CyberSolver, Вы так говорите, будто тут пишется ЦЕЛОЕ приложение которое решает мировой кризис.
Это самый обычный пример, он вместо этого int может подставить любой тип данных, любой класс, так что я правильно всё посоветовал!

Добавлено через 33 секунды
Более того я яву не знаю.
_Ivana
2177 / 1382 / 124
Регистрация: 01.03.2013
Сообщений: 4,120
Записей в блоге: 2
02.08.2014, 13:47     Возвращение ссылки на локальную переменную #13
Я не знаком с С++, но где-то краем уха слышал, что например в С malloc всегда поступает именно таким образом - возвращает ссылку на локальную переменную, и никто не делает из этого трагедии...
CyberSolver
 Аватар для CyberSolver
101 / 74 / 17
Регистрация: 23.07.2014
Сообщений: 686
Записей в блоге: 1
02.08.2014, 14:10     Возвращение ссылки на локальную переменную #14
_Ivana, не иначе как от агенства ОБС.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.08.2014, 22:01     Возвращение ссылки на локальную переменную
Еще ссылки по теме:

Как локальную переменную сделать глобально, при это сохранив накопленное в ней значение? C++
Возвращение значения в функции, ссылки, вычислить корни квадратного уравнения C++
C++ VS2010 отладчик не видит локальную переменную

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
02.08.2014, 22:01     Возвращение ссылки на локальную переменную #15
Цитата Сообщение от _Ivana Посмотреть сообщение
Я не знаком с С++, но где-то краем уха слышал,
Давайте вот без таких бабушких сказочек.
Цитата Сообщение от _Ivana Посмотреть сообщение
в С malloc всегда поступает именно таким образом - возвращает ссылку на локальную переменную
В Си нет ссылок.
Yandex
Объявления
02.08.2014, 22:01     Возвращение ссылки на локальную переменную
Ответ Создать тему
Опции темы

Текущее время: 01:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru