Returning a reference can work?

匿名 (未验证) 提交于 2019-12-03 02:38:01

问题:

I used to think returning a reference is bad as our returned reference will refer to some garbage value. But this code works (matrix is a class):

const int max_matrix_temp = 7; matrix&get_matrix_temp()     {    static int nbuf = 0;      static matrix buf[max_matrix_temp];       if(nbuf == max_matrix_temp)           nbuf = 0;       return buf[nbuf++]; }   matrix& operator+(const matrix&arg1, const matrix&arg2) {       matrix& res = get_matrix_temp();     //...       return res; } 

What is buf doing here and how does it save us from having garbage values?

回答1:

I see no buf declared anywhere, which means it doesn't go out of scope with function return, so it's okay. (it actually looks like it's meant to be matrixbuf which is also fine, because it's static).

EDIT: Thanks to R. Martinho Fernandes for the guess. Of course it is matrix buf, so it makes buf static array in which temporary is allocated to make sure it doesn't get freed when the function returns and therefore the return value is still valid.



回答2:

buf is declared as static, meaning it retains it's value between calls to the function:

static matrix buf[max_matrix_temp]; 

i.e. it's not created on the stack as int i = 0; would be (a non-static local variable), so returning a reference to it is perfectly safe.

This following code is dangerous, because the memory for the variable's value is on the stack, so when the function returns and we move back up the stack to the previous function, all of the memory reservations local to the function cease to exist:

int * GetAnInt() {   int i = 0;  // create i on the stack   return &i;  // return a pointer to that memory address } 



回答3:

This is safe up to a point, but very dangerous. The returned reference can't dangle, but if client code keeps it around, at some future point, the client is in for a big surprise, as his value suddenly changes to a new return value. And if you call get_matrix_temp more than max_matrix_temp times in a single expression, you're going to end up overwriting data as well.

In the days before std::string, in code using printf, I used this technique for returning conversions of user defined types, where a "%s" specifier was used, and the argument was a call to a formatting function. Again, max_matrix_temp was the weak point: a single printf which formatted more instances of my type would output wrong data. It was a bad idea then, and it's a worse idea now.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!