#include
using namespace std;
class example
{
public:
example()
{
num = new int;
*num = 10;
cout<<"num = "<<*num<<endl;
cout<<"构造"<<endl;
}
~example()
{
cout<<"析构"<<endl;
delete num;
}
void pingfang()
{
*num *= *num;
}
void print()
{
cout<<*num<<endl;
}
private:
int *num;
};
example & diaoyong1()
{
example * p = new example;
p->pingfang();
return *p;
}
example * diaoyong2()
{
example * p = new example;
p->pingfang();
return p;
}
int main(void)
{
example & e1 = diaoyong1();
e1.print();
delete &e1;
example * ptr = diaoyong2();
ptr->print();
delete ptr;
getchar();
return 0;
}
char *&alloc(){ char *va = new char [100]; return va;}
对于这样的程序 执行过程为
进入函数alloc
为变量va分配内存 假设为0x12345678 大小为四个字节 (32位机指针)
执行new操作 在内存0x12345678地址存入申请到的内存地址 假设为0x45670abc
也就是说 *(0x12345678)=0x45670abc
以上部分应该很好理解
然后返回va 也就是返回上一层一个值 这个值不可能是悬空的 它需要一个地址来存 由于是引用返回,所以返回的地址实际上就是变量va的地址0x12345678
退出函数 释放临时变量 包括va的地址0x12345678
返回到主调函数,使用返回值 比如赋值 a=alloc(); 相当于执行操作
a=*(0x12345678) 注意 在上一步 这个地址已经被释放了 所以当前这个地址存的是什么东西是不确定的 可能还是0x45670abc 也可能已经有了变化
这样a的值就不一定是你需要的了 结果也就可能是错的
关键在于退出函数 释放内存 使用内存这步 先释放 后使用 于是出错
如果是全局/静态变量 自然不会有这个问题 因为内存依旧被原来变量占用 类似引用做参数也是同样的效果
example & diaoyong1()
{
example * p = new example;
p->pingfang();
return *p;
}
example * diaoyong2()
{
example * p = new example;
p->pingfang();
return p;
}
我想问上面的两个函数有什么不同?函数返回值到底是怎么实现的?如果返回一个指针是不是就是将储存这个指针的地址返回回来,函数怎么返回和左值是什么类型是不是有关系?局部变量的指针在函数结束的时候被释放是不是储存这个指针的地址释放了这个指针?
example & e1 = diaoyong1();
example * e1 = diaoyong1();
//这两个本质上有什么区别,第一个为什么不会造成内存的泄露?
需要理解一下内存的分部才醒,一般的函数的局部变量都是存储在栈中,栈中的对象在函数结束时自动释放,使用new开辟的空间是在内存的堆区,对于
由于是手动开辟,手动释放,也就是说即使是在函数内部开辟的空间,函数结束了也不会自动的回收,针对你上面的例子,第一个函数diaoyong1中的p
是个临时变量他指向堆中的一段内存,但是*p是对指针的提取代表的是实际的对象,也就说返回的是实际的对象,例子二中的函数你返回的是对象的地址
由于你是开辟的堆中所以该对象的地址除非是你手动的delete掉不然一直存在,本质来说两个函数没有什么大的区别,都是在堆上开辟了空间,只不过返回的
东西不同,一个是对象本身,一个是对象的地址