Создание константной lvalue-ссылки из возврата по значению: как это работает?

Отсюда я узнал, что константная ссылка может быть сделана из объекта, возвращаемого значением функцией. Но теперь я спросил себя: куда поместить этот объект, чтобы он был безопасным и не перезаписывался стеками будущих вызовов функций?

Рассмотрим этот код:

#include <iostream>
using namespace std;

struct A{};

A returnsmt(){
    int avariable;
    cout<<"returnsmt stack: "<<&avariable<<endl;
    return A();
}

const A& proxyreturnsmt(){
    int avariable;
    const A& middle=returnsmt();
    cout<<"proxyreturnsmt stack: "<<&avariable<<" A ptr: "<<&middle<<endl;
    return middle;
}

int main(){
    int avariable;
    const A& a=proxyreturnsmt();
    cout<<"main stack: "<<&avariable<<" A ptr: "<<&a<<endl;
}

Теперь даже невозможно, чтобы main знает, что он собирается создать ссылку из объекта стека, поэтому уловка не может заключаться в том, что он передает скрытый указатель на собственное ведро свободного стека. Этот код на g++ печатает:

returnsmt stack: 0x7fff3718bc0c
proxyreturnsmt stack: 0x7fff3718bc28 A ptr: 0x7fff3718bc2f
main stack: 0x7fff3718bc4c A ptr: 0x7fff3718bc2f

так что, если стек растет вниз, то место, где находится объект, proxyreturnsmtстек Почему вы не столкнетесь с проблемами, если, получив эту справку, позвоните, скажем, function_with_big_stack_allocи так наверняка исправят старые proxyreturnsmtстек для нового использования?

1 ответ

Решение

Программа демонстрирует неопределенное поведение. В proxyreturnsmtсвязываешь middle на временный объект. Время жизни этого временного объекта продлевается только до middle выходит за рамки.

Затем вы возвращаете ссылку на middle; но объект, на который он ссылается, уничтожается при возврате функции. Итак, в mainгде вы связываете a к результату звонка proxyreturnsmt, a является висячей ссылкой (объект, на который она ссылается, больше не существует).

Когда вы пытаетесь использовать ссылку (беря адрес ссылочного объекта, который больше не существует), программа демонстрирует неопределенное поведение.

Другие вопросы по тегам