2011-01-15 2 views
3

См. Следующие фрагменты кода. Во второй функции я возвращаю ссылку. Я объявляю локальную переменную в функции и возвращаю адрес. Поскольку переменная локальна, я верю, что ее жизнь заканчивается, когда она выходит из функции. Мой вопрос: почему можно получить доступ к значению от вызывающего без каких-либо исключений, даже если исходная переменная удалена?Возврат по ссылке

int& b=funcMulRef(20,3); 

int* a= funcMul(20,3); 


int* funcMul(int x,int y) 
{ 
int* MulRes = new int; 
     *MulRes = (x*y); 

return MulRes; 

} 

int& funcMulRef(int x,int y) 
{ 
int MulRes ; 
     MulRes = (x*y); 

return MulRes; 

} 

Привет, JOHN

+0

на funcMul, я думаю, вы имеете в виду '* MulRes = (x * y)' – Muggen

+0

@Muggen. Спасибо, что указали это. Исправлено сейчас. –

ответ

7

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

+0

Почему первая функция не будет компилироваться? Кроме того, +1 – Muggen

+1

@Muggen: вы не можете назначить целое число указателю. –

+0

ах в порядке. Я думал, что есть что-то еще. ty – Muggen

2

Доступ к данным, которые больше не входят в сферу действия.

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

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

2

Оригинальное значение не удаляется. Просто потому, что действие по его удалению вызовет некоторые невидимые вычисления.

Значение по-прежнему существует, но пространство памяти больше не принадлежит вам и на самом деле не определено.

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

2

Нет, вы не должны этого делать. Результат доступа к остаточным данным в стеке не определен. Кроме того, если ваше возвращаемое значение имеет тип класса, его деструктор уже будет вызван.

Вы пытаетесь избежать временных объектов? Если да, то вы могли бы быть заинтересованы в этом:
http://en.wikipedia.org/wiki/Return_value_optimization

0

Это, скорее всего, не будет работать в следующих случаях:

funcMulRef(10,3) + funcMulRef(100,500) 

в качестве альтернативы, более противным образом:

std::cout << "10*3=" << funcMulRef(10,3) << " 100*500=" << funcMulRef(100,500) << std::endl; 

gcc предупреждает об ошибках такого типа, если вы используете -Wall

Смежные вопросы