C/C++

Глобальная переменная. (Си)

Есть большая разница между таким объявлением переменной
int *a=NULL;
int main()
{
int arr[]={1,2,3,4,5};
if(arr[0]<arr[1]){
a=&arr[0];
}
else{a=&arr[1];}
printf("%d\n", *a);
return 0; //address of stack memory associated with local variable 'arr' is still referred to be the global variable 'a' upon returning to the caller. this will be dangling reference
}

И таким?

int main()
{
int *a=NULL;
int arr[]={1,2,3,4,5};
if(arr[0]<arr[1]){
a=&arr[0];
}
else{a=&arr[1];}
printf("%d\n", *a);
return 0;
}
В первом случае получаю предупреждение
address of stack memory associated with local variable 'arr' is still referred to be the global variable 'a' upon returning to the caller. this will be dangling reference
адрес памяти стека, связанный с локальной переменной 'arr', по-прежнему называется глобальной переменной 'a' после возврата к вызывающей стороне. это будет висячая ссылка

Что это значит?
Botirbek Boyakhmedov
Botirbek Boyakhmedov
288
Компилятору всё равно - main это или какая-то иная подпрограмма. Он априори считает, что любая подпрограмма работает только некоторую часть общего времени работы программы.

В первом случае глобальная переменная a существует всё время жизни программы, но локальная переменная arr существует в стеке только во время работы main. И как только main завершается, место в стеке, занимаемое arr, отдаётся другой подпрограмме для совершенно иных целей. Потому, после завершения main переменная a будет ссылаться уже не на содержимое arr, а на неизвестно что. Вот об этом тебя и предупреждают.

Во втором случае локальная переменная a создаётся и уничтожается одновременно с локальной переменной arr - проблемы не возникает.

И, кстати, не надо a=&arr[0];. Значение arr - это и есть адрес начала массива.
Так что достаточно: a = arr;
Игорь Жупанов
Игорь Жупанов
71 259
Лучший ответ
Глобальная переменная существует даже после выхода из функции (после выхода из main это не столь важно, но для деструкторов в С++ тоже может оказаться важным). Компилятор выдает предупреждение, что указатель после выхода из функции будет показывать в неизвестно как распределенную область памяти, т. е. - потенциальная ошибка.
Antonio Montana
Antonio Montana
57 617
Да, есть. В случае завершения функции, при первом случае, переменная остаётся в памяти (а в C и C++ за памятью следит сам программист), во втором случае - исчезает вместе с функцией
Timofey Galay
Timofey Galay
8 067