Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Pointer do zmiennej lokalnej, a zasięg

Ostatnio zmodyfikowano 2016-09-05 13:37
Autor Wiadomość
jjj
Temat założony przez niniejszego użytkownika
Pointer do zmiennej lokalnej, a zasięg
» 2016-09-05 00:59:42
C/C++
#include <iostream>

using namespace std;

int main()
{
    int * a = NULL;
    {
        static int b = 3;
        a = & b;
    }
    cout << * a;
}

Rozumiem, że zmienna static żyje tak długo jak żyje program i powyższy kod przy kompilacji daje prawidłową wartość: 3.
A dlaczego przy pominięciu static, gdy zmienna jest automatyczna, tak samo dostaję wynik 3, zamiast jakiejś nieokreślonej wartości?
A, gdy wrzuciłem kod w ideone (bez static w int b ofc), dostaje wynik 0.
P-151446
Rashmistrz
» 2016-09-05 01:47:12
zmienna static żyje tak długo jak żyje program
Tak na prawdę są one zmiennymi globalnymi,
tylko że o ograniczonym zasięgu.
Co ciekawsze, mają one stały adres
w przestrzeni adresowej procesu. ;)

dlaczego przy pominięciu static,
[...], tak samo dostaję wynik 3,
zamiast jakiejś nieokreślonej wartości?
W przeciwieństwie do zmiennych statycznych,
zmienne lokalne przechowywane są na stosie w tzw. ramce stosu.

W tamtym bloku kodu gdy masz jeszcze dostęp do zmiennej B,
zapisujesz adres zmiennej, która znajduje się na stosie.

Tak na prawdę tracisz w tym przypadku tylko zasięg do zmiennej B,
a ona nadal się znajduje na stosie jako "zmienna lokalna" funkcji main.

Jest duże prawdopodobieństwo, że wartość znajdująca się
pod tym adresem nie ulegnie zmianie, jednak nie jest to zapewnione.

Mówię "w tym przypadku", bo z funkcji main, wychodzi się tylko raz.
Gdybyś zwracał adres zmiennej lokalnej z wywołanej funkcji,
to byłby podobny przypadek, ale następne wywołanie dowolnej
funkcji nadpisze tą wartość... nawet jeśli nie tą samą wartością.

Adres to adres... magia stosu!
P-151447
jjj
Temat założony przez niniejszego użytkownika
» 2016-09-05 01:59:22
Ciekawe, ja sobie tłumaczyłem to tak, że po wyjściu z każdego bloku następuje wyrzucenie zmiennej z stosu i wtedy odwołuje się do nieokreślonego bloku pamięci. Dziękuję za odpowiedz :)
P-151448
karambaHZP
» 2016-09-05 06:03:42
Jest duże prawdopodobieństwo, że wartość znajdująca się
pod tym adresem nie ulegnie zmianie, jednak nie jest to zapewnione.
Zmienna lokalna po opuszczeniu bloku instrukcji traci ważność, więc odwołanie do jej adresu spoza tego bloku jest niezdefiniowanym zachowaniem.
P-151449
jjj
Temat założony przez niniejszego użytkownika
» 2016-09-05 13:37:42
Tak jak mowił Rachmistrz, taki kod nadpisuje tę wartość.
C/C++
#include <iostream>

using namespace std;

int * func1()
{
    int a = 1;
    return & a;
}

void func2()
{
    int var1 = 2;
}

void func3()
{
    int var2 = 5;
}

int main()
{
    int * p = func1();
    cout << * p << "\n";
    func2();
    cout << * p << "\n";
    func3();
    cout << * p;
}

W dodatku juz gdy skompiluje program z optymalizacja to program zwraca rozne liczby. Undefined behaviour, wiec nie ma co na tym sie rozwodzic :)
P-151452
« 1 »
  Strona 1 z 1