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

Как это работает? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.69
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
28.09.2011, 17:57     Как это работает? #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
int *fun()
{
    int a = 5;
    return &a;
}
int main()
{
        int *ptr = fun();
        std::cout << *ptr;
        system( "pause" );
        return 0;
}
Как я это себе представляю: функция fun возвращает адрес автоматической переменной. Но эта переменная при завершении работы функции fun уничтожается, поэтому указатель ptr указывает на недействительную память.
Даже компилятор выдает это :warning C4172: возвращение адреса локальной или временной переменной

Так почему это работает?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.09.2011, 17:57     Как это работает?
Посмотрите здесь:

C++ Как это работает
C++ объясните как это работает
C++ Как это работает?
Как это работает? C++
Русификация.Работает-супер! Обьяснитте, как это работает? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nxnx
Формучанин
361 / 292 / 16
Регистрация: 02.11.2010
Сообщений: 1,226
28.09.2011, 17:59     Как это работает? #2
Цитата Сообщение от Chelioss Посмотреть сообщение
Так почему это работает?
где написано что запрещено возвращать неправильный адрес?
если выводит правильное значение-это совпадение.
Для более подробной информации нужно прогнать в отладчике и глянуть как меняется стек.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
28.09.2011, 18:05  [ТС]     Как это работает? #3
Я не про возвращение адреса говорю.
Почему выводится число 5?

Добавлено через 1 минуту
Цитата Сообщение от nxnx Посмотреть сообщение
если выводит правильное значение-это совпадение.
Поменял несколько раз значение, которым специализируется переменная a и все время выводит правильно.

Добавлено через 1 минуту
Похоже я понял, почему работает. Переменная уничтожается, но та область памяти, в которой хранилась значение 5, остается не измененной, т.е. в ней по прежнему находится набор битов соответствующей цифре 5.

Я думал, что доступ возможен только к той памяти, которая выделяется программой, но оказывается можно спокойно работать со всей доступной памятью. Хотя я наверно не совсем правильно говорю.
nxnx
Формучанин
361 / 292 / 16
Регистрация: 02.11.2010
Сообщений: 1,226
28.09.2011, 18:11     Как это работает? #4
чтобы лучше понять, можно попробовать собрать такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <cstdlib>
int *fun()
{
        int a = 5;
        return &a;
}
int fun2()
{
    int b=10;
    return b*0;
}
int main()
{
       
    int *ptr = fun();
    fun2();
    std::cout << *ptr<<"\n";
    system( "pause" );
       
        return 0;
}
и желательно с выключенной оптимизацией. Для понимания- прогнать через отладчик.
ISergey
Maniac
Эксперт С++
 Аватар для ISergey
1330 / 863 / 50
Регистрация: 02.01.2009
Сообщений: 2,622
Записей в блоге: 1
28.09.2011, 18:11     Как это работает? #5
Цитата Сообщение от Chelioss Посмотреть сообщение
Похоже я понял, почему работает. Переменная уничтожается, но та область памяти, в которой хранилась значение 5, остается не измененной, т.е. в ней по прежнему находится набор битов соответствующей цифре 5.
Должно быть так...
но компилятор по хитрому сделал))
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
int *fun()
{
    int a = 5;
    return &a;
}
int main()
{
    int *ptr = fun();
    std::cout << *ptr;
00401000 8B 0D 48 20 40 00    mov         ecx,dword ptr [__imp_std::cout (402048h)]  
00401006 6A 05                push        5  ; !
00401008 FF 15 44 20 40 00    call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402044h)]  
    system( "pause" );
0040100E 68 F4 20 40 00       push        offset string "pause" (4020F4h)  
00401013 FF 15 A8 20 40 00    call        dword ptr [__imp__system (4020A8h)]  
00401019 83 C4 04             add         esp,4  
    return 0;
0040101C 33 C0                xor         eax,eax  
}
0040101E C3                   ret
Проще говоря код так переделал..
C++
1
std::cout << 5 ;
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
28.09.2011, 18:17     Как это работает? #6
Даже если компилятор бы так не веселился, оно бы "работало". Шутка в том, что область памяти освобождается, но не перезаписывается тут же. В ней лежит все тот же элемент, хоть ячейка и отдана уже в пул. Её можно использовать, но никто не гарантирует, что в какой-то определенный момент времени она не будет снова выделена.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
28.09.2011, 18:18  [ТС]     Как это работает? #7
Т.е. я правильно понял и мое утверждение верно.
ISergey
Maniac
Эксперт С++
 Аватар для ISergey
1330 / 863 / 50
Регистрация: 02.01.2009
Сообщений: 2,622
Записей в блоге: 1
28.09.2011, 18:23     Как это работает? #8
Переменная в стеке должна лежать.. так как стек не затерся она целой осталась..
Если включить отладочный режим оно так и будет..
LosAngeles
Заблокирован
28.09.2011, 18:24     Как это работает? #9
Цитата Сообщение от DKOI Посмотреть сообщение
хоть ячейка и отдана уже в пул
ни в какой пул никакая ячейка не была отдана, это стек
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
28.09.2011, 18:29     Как это работает? #10
Цитата Сообщение от LosAngeles Посмотреть сообщение
ни в какой пул никакая ячейка не была отдана, это стек
Говоря пул, я не подразумеваю системный пул памяти, а подразумеваю, что адрес памяти уже не "привязан" и может снова быть "выделен". Извиняюсь за терминологию, если вам не нравится такое использование.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
28.09.2011, 18:34  [ТС]     Как это работает? #11
Цитата Сообщение от ISergey Посмотреть сообщение
Переменная в стеке должна лежать.. так как стек не затерся она целой осталась..
Если включить отладочный режим оно так и будет..
Не понял. После окончании работы функции, "функция выталкивается из вершины стэка"
и память, отведенная автоматическим переменным, освобождается, но не изменяется.
Я так и не понял причем тут стэк, если дело в памяти.
DKOI я думаю, сказал более правильно.
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
28.09.2011, 18:36     Как это работает? #12
Локальные переменные функции хранятся в стеке.
ISergey
Maniac
Эксперт С++
 Аватар для ISergey
1330 / 863 / 50
Регистрация: 02.01.2009
Сообщений: 2,622
Записей в блоге: 1
28.09.2011, 18:38     Как это работает? #13
Chelioss, http://asmworld.ru/uchebnyj-kurs/026...ye-peremennye/
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
28.09.2011, 18:38  [ТС]     Как это работает? #14
Цитата Сообщение от DKOI Посмотреть сообщение
Локальные переменные функции хранятся в стеке.
А стэк хранится в единой памяти, отведенной системой для программы, разве не так?
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
28.09.2011, 18:40     Как это работает? #15
Цитата Сообщение от Chelioss Посмотреть сообщение
А стэк хранится в единой памяти, отведенной системой для программы, разве не так?
Так то оно так, но не совсем. Для системы, стек процесса - несколько отличная от кучи или сегмента данных структура.
nxnx
Формучанин
361 / 292 / 16
Регистрация: 02.11.2010
Сообщений: 1,226
28.09.2011, 18:43     Как это работает? #16
стек это отдельная страница памяти, которая выделяется при запуске программы.
регистр esp указывает на вершину стека.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
28.09.2011, 18:44  [ТС]     Как это работает? #17
Ответ на мой вопрос в первом посте:
При уничтожении переменной, память освобождается от привязки, но не изменяется. С чужой памятью можно работать.( памятью, отведенной системы для программы)
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
28.09.2011, 18:46     Как это работает? #18
да UB тут и всё.
так вышло случайно.

да и вы сами написали
Цитата Сообщение от Chelioss Посмотреть сообщение
При уничтожении переменной, память освобождается от привязки, но не изменяется. С чужой памятью можно работать.( памятью, отведенной системы для программы)
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
28.09.2011, 18:47  [ТС]     Как это работает? #19
Цитата Сообщение от OstapBender Посмотреть сообщение
да UB тут и всё.
так вышло случайно.
Что такое UB?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.09.2011, 18:49     Как это работает?
Еще ссылки по теме:

C++ Как это работает?
C++ Как это работает?
Как это работает? Я хочу спросить как работает C++ и где можно про него почитать C++

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

Или воспользуйтесь поиском по форуму:
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
28.09.2011, 18:49     Как это работает? #20
Цитата Сообщение от Chelioss Посмотреть сообщение
Что такое UB?
Недокументированная особенность.
Yandex
Объявления
28.09.2011, 18:49     Как это работает?
Ответ Создать тему
Опции темы

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