освобождение после завершения сферы

Возможный дубликат:
Возврат адреса локальной или временной переменной
Можно ли получить доступ к памяти локальной переменной вне ее области?

Предположим, у нас есть следующий код

int *p;//global pointer
void foo() {
int a=10;//created in stack
p = &a;
}//after this a should be deallocated and p should be now a dangling pointer
int main() {
foo();
cout << *p << endl;
}

Я хотел знать, почему это работает .. это должно быть ошибка сегмента!

ОК, неопределенное поведение кажется подходящим .. Можете ли вы еще раз проверить это? Я попытался смоделировать вышеупомянутую вещь в следующем коде, но теперь он дает SIGSEGV.

int main() {
int *p=NULL;
{
int i=5;
int *q = &i;
p=q;
delete q;//simulates the deallocation if not deallocated by the destructor..so p becomes a dangling pointer
}
cout << *p << endl;
}

1

Решение

Вы написали программу, которая имеет Неопределенное поведение. UB не означает ошибку сегмента, это означает, что все может произойти. Вы запустили свою программу, и что-то случилось, но не то, что вы ожидали. Мораль этой истории заключается в том, что вы не пишете программы на UB, и вам очень трудно это понять.

3

Другие решения

Вы не должны использовать глобальные переменные. В вашем примере то, что вы сделали, это неопределенное поведение.

Если бы вы сделали что-то вроде

int* foo() {
int a = 10; //created in stack
return &a;
}

int main() {
int *p = foo();
cout << *p << endl;
}

Вы бы получили предупреждение по крайней мере:

prog.cpp:5: warning: address of local variable ‘a’ returned

Вы должны относиться к этим предупреждениям очень серьезно.

1

Когда вы определяете переменную в функции, она будет размещена в стеке, и когда ваш возврат из этой функции, деструктор этой переменной будет вызываться автоматически (если тип имеет какой-либо деструктор), но в отличие от объектов, выделенных в куче, память стека не освобождается при эта точка:

void test1() {
// assume on start of this function top of stack is 0x100
int a = 10; // push 10 on to of stack and increase top of stack
// Now top of stack is 0x100 + sizeof(int)
a = 20;     // when you do this you are actually changing variable on stack
p = &a;     // Get address of variable in stack!
// So p is now 0x100
// hidden return will restore top of stack to 0x100, pop return address, ...
}
int test2() {
// again top of stack is 0x100
int a2;     // a2 is in same address as a in previous function!
a2 = 100;   // so this will overwrite value that pointed by p
// because it point to same location
return (int)&a2;
}

void main() {
test1();
test2();
std::cout << *p << std::endl;
}

Но если ваш тип является классом, который имеет деструктор и нуждается в конструкции перед использованием, вы можете даже получить исключения, такие как ошибка сегментации

-1
По вопросам рекламы [email protected]