2012-06-21 2 views
5

Я не понимаю, как этот пример может возможно работать:Возвращаясь указатель

double * GetSalary() { 
    double salary = 26.48; 
    return &salary; 
} 

main() { 
    cout << *GetSalary(); //prints 26.48 

} 

salary является локальной переменной в GetSalary(), что после возвращения из функции, эта ячейка может возможно быть перезаписаны другой функцией. Я не вижу, как может возвращаться указатель на локальную переменную (не instanciated на кучу).

+6

Да, возможно, это может быть перезаписано. Или это не так. Вот почему это называется ** неопределенным поведением **, а не ** гарантированным сбоем **. –

+0

его смешно, что код obove является первым результатом, когда я возвращаю указатель google для функции « – user695652

+0

Я часто получаю то же самое. У меня есть идея, что Google изменит ваш поисковый пузырь, когда вы вошли в систему с учетной записью Google. –

ответ

16

Не работает. Это неопределенное поведение. Возможно, это работает, потому что «правильное поведение» является подмножеством «любого возможного поведения».

8

Вы столкнулись с неопределенным поведением, что означает все может случиться. Включая работу.

За пределами функции обратный указатель висит (то есть память, на которую указывает указывает, является недопустимой).

Почему это, кажется, работает, сводится к реализации. Скорее всего, память не очищается. Поэтому, хотя у вас нет доступа к тому, на что указывает указатель возврата, в этой памяти все еще существует 26.48. Но это просто случайно.

1

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

Чтобы понять, почему это происходит, вам необходимо проанализировать точный шаблон сдвига кадров стека, который является довольно раздражающим и очень зависимым от компилятора.

0

Это dangling pointer, который вызывает undefined behaviour.
В некоторых системах это может привести к сбою вашего приложения, а для других он может работать корректно. Но в любом случае вы не должны этого делать.
см. this similar SO post.

2
double * GetSalary() 
{ 
    double salary = 26.48;  
    return &salary; 
} 
double dummy_function() 
{ 
    double a = 1.1; 
    double b = 2.2; 
    double c = 0 , d = 0; 

    c = a + b - d; 
    return c; 
} 

main() 
{  
    double *a; 
    a = GetSalary(); 
    cout << dummy_function(); 
    cout << *a; //this time it wont print 26.48 
} 

Поскольку стек функция была перезаписана второй вызов функции dummy_function

0

Это также работает, но гораздо безопаснее. Это не будет работать в многопоточной программе.

double * GetSalary() { 
    static double salary = 26.48; 
    return &salary; 
} 
Смежные вопросы