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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Gwini
10 / 10 / 3
Регистрация: 08.03.2014
Сообщений: 70
#1

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

02.08.2014, 05:12. Просмотров 1076. Ответов 14
Метки нет (Все метки)

Заметил недавно одну интересную вещь. Как вообще работает такой код? Причем коректно.
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;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.08.2014, 05:12
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Возвращение ссылки на локальную переменную (C++):

Возврат ссылки на локальную переменную - C++
Привет, есть такой код: int*&amp; change(void) { int* x(new int(50)); return x; } int main(void) {

Возвращение ссылки из функции - C++
Привет, я немного не понимаю, почему в следующем коде в строках 16-17 надо возвращать именно ссылку: #include &lt;iostream&gt; #include...

Возвращение ссылки на локальный объект - C++
В каком-то коде мельком видел что-то вроде: char&amp; char_stub() { char c; return c; }; int main() {

Возвращение const ссылки на временный объект - C++
Добрый вечер, #include &lt;iostream&gt; using namespace std; struct Point { int _x; int _y; };

Передать локальную переменную в новую функцию - C++
#include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;sstream&gt; #include &lt;string&gt; #include &lt;windows.h&gt; using namespace std; int...

VS2010 отладчик не видит локальную переменную - C++
Добрый день! С чем это может быть связано?

14
CyberSolver
101 / 74 / 17
Регистрация: 23.07.2014
Сообщений: 686
Записей в блоге: 1
02.08.2014, 05:18 #2
Gwini, не очень-то корректно.
0
Gwini
10 / 10 / 3
Регистрация: 08.03.2014
Сообщений: 70
02.08.2014, 05:21  [ТС] #3
Цитата Сообщение от CyberSolver Посмотреть сообщение
Gwini, не очень-то корректно.
vs выводит 99
0
CyberSolver
101 / 74 / 17
Регистрация: 23.07.2014
Сообщений: 686
Записей в блоге: 1
02.08.2014, 05:26 #4
Gwini, а как вы думаете, что будет с локальной переменной по выходу из функции?
0
Gwini
10 / 10 / 3
Регистрация: 08.03.2014
Сообщений: 70
02.08.2014, 05:31  [ТС] #5
Цитата Сообщение от CyberSolver Посмотреть сообщение
Gwini, а как вы думаете, что будет с локальной переменной по выходу из функции?
Ну должна удалиться, но она существует не в main() и после завершения func() ccылатся уже не на что. Я просто читал что такого делать нельзя, а тут на тебе...
0
gray_fox
What a waste!
1521 / 1226 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
02.08.2014, 06:25 #6
Цитата Сообщение от Gwini Посмотреть сообщение
vs выводит 99
Просто так звёзды совпали, это ничего не значит.
0
Бендерродригез
Сгибальщик
42 / 42 / 3
Регистрация: 18.05.2013
Сообщений: 220
Завершенные тесты: 1
02.08.2014, 07:14 #7
Цитата Сообщение от gray_fox Посмотреть сообщение
Просто так звёзды совпали, это ничего не значит.
Или cout внезапно принимает &&.
0
gray_fox
What a waste!
1521 / 1226 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
02.08.2014, 07:24 #8
Цитата Сообщение от Бендерродригез Посмотреть сообщение
Или cout внезапно принимает &&.
Возвращаемый тип lvalue же, ссылка на rvalue тут вообще не при чём.
0
Andrej
И целого heap'а мало
94 / 55 / 9
Регистрация: 31.07.2014
Сообщений: 291
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:
Хотя, можно и проще стэк затереть.
0
__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;
}

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

Добавлено через 33 секунды
Более того я яву не знаю.
0
_Ivana
3169 / 1786 / 153
Регистрация: 01.03.2013
Сообщений: 5,004
Записей в блоге: 2
02.08.2014, 13:47 #13
Я не знаком с С++, но где-то краем уха слышал, что например в С malloc всегда поступает именно таким образом - возвращает ссылку на локальную переменную, и никто не делает из этого трагедии...
0
CyberSolver
101 / 74 / 17
Регистрация: 23.07.2014
Сообщений: 686
Записей в блоге: 1
02.08.2014, 14:10 #14
_Ivana, не иначе как от агенства ОБС.
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
02.08.2014, 22:01 #15
Цитата Сообщение от _Ivana Посмотреть сообщение
Я не знаком с С++, но где-то краем уха слышал,
Давайте вот без таких бабушких сказочек.
Цитата Сообщение от _Ivana Посмотреть сообщение
в С malloc всегда поступает именно таким образом - возвращает ссылку на локальную переменную
В Си нет ссылок.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.08.2014, 22:01
Привет! Вот еще темы с ответами:

Ошибка E2363 Попытка возвратить локальную переменную - C++
Такую ошибку выдает компилятор Embarcadero, в Студии почему то ее не выдает, мне нужно сделать так чтобы и в эмбаркадеро не выдавало...

Возвращение ссылки на локальный объект - C++
int&amp; foo() { int a; //: warning C4172: возвращение адреса локальной или временной переменной return a; } ...

Не могу заставить g++ не инициализировать локальную переменную нулем - C++
Привет! Есть такой код (из серии &quot;что будет напечатано на экран&quot;) #include &lt;iostream&gt; using namespace std; int x = 1; ...

Возвращение ссылки на указатель использование её как левостороннего значения - C++
Есть шаблон: //------------------------------------------------------- template&lt;class T&gt; struct ts { private: void* data; ...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
02.08.2014, 22:01
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru