现在的位置: 首页 > 综合 > 正文

返回指向局部变量指针的函数 与 返回局部变量引用的函数

2014年01月03日 ⁄ 综合 ⁄ 共 1349字 ⁄ 字号 评论关闭
#include "stdafx.h"
#include<iostream>
#include<ostream>
#include<istream>

int& rref()
{
	int i = 11;
	return i;
}


int* rpot()
{
	int j = 33;
	return &j;
}


int _tmain(int argc, _TCHAR* argv[])
{
	int &a = rref();
	int *b = rpot();
	std::cout<<"ref "<<a<<'\n';
	std::cout<<"pot"<<*b<<'\n';
	int c(2);
	std::cin>>c;

	return 0;
}

如以上两个函数rref,rpot,分别返回指向局部变量的引用和指针。

如果在测试时,_tmain只有函数rref

int &a = rref();
std::cout<<"ref "<<a<<'\n';

结果为ref11正确

如果_tmain只有函数rpot

int *b = rpot();
std::cout<<"pot"<<*b<<'\n';

结果为pot33正确

但是如果同时出现

int _tmain(int argc, _TCHAR* argv[])
{
	int &a = rref();
	int *b = rpot();
	std::cout<<"ref "<<a<<'\n';
	std::cout<<"pot"<<*b<<'\n';
	int c(2);
	std::cin>>c;

	return 0;
}

结果为

ref 33

pot1834244

出现错误。

逐步调试程序,

当程序运行到

int *b = rpot();

此时a为11正确。

但是当运行到

std::cout<<"ref "<<a<<'\n';

a = 33

b = 0x0030f914

运行到

std::cout<<"pot"<<*b<<'\n';

*b = 3209748

a = 3209748

通过更改函数rpot中j的值,可以看出当程序运行到

std::cout<<"ref "<<a<<'\n';

本来引用i的引用a却引用了 j 的值。

        当函数返回引用时,没有复制返回值,而是返回对象本身。

        返回引用的函数返回一个左值,这样的函数可以用在任何要求使用左值的地方。

          

        不要返回局部变量的引用或指针,因为一旦函数结束,局部变量被释放,对局部变量的引用会指向不确定的内存,返回的指针变成了悬垂指针。

     

        出现上述错误的原因很可能是因为调用rref结束后,分配给局部变量i的存储空间被释放,此时对局部对象的引用即a指向不确定的内存,在本程序中a仍指向这个内存。

        当调用rpot时,因为局部变量i的存储空间被释放,该存储空间分给了局部变量j,此时值为33,所以运行

std::cout<<"ref "<<a<<'\n';

        ,a为33.

       但是接下来运行

std::cout<<"pot"<<*b<<'\n';

的结果无法解释。

请问两者直接是如何影响的?

如果是类的话会不会出现同样情况?

在《More effective c++》一书中,介绍vitual copy constructor时,派生类成员函数返回了局部变量的指针

virtual FirstCom * getCopy() const{
return new FirstCom(*this);
}

抱歉!评论已关闭.