读书人

关于作用域的1点疑惑

发布时间: 2013-10-04 21:41:43 作者: rapoo

关于作用域的一点疑惑
以下testPointer()函数在调用完成后,其作用域应该就结束了,其中point分配的内存应该被系统回收了
但是为嘛还能再访问一次
#include "stdafx.h"
#include "iostream"
//#define using name std;
using namespace std;
class CvPoint
{
public:
int x;
int y;
};

CvPoint* testPointer()
{
//CvPoint* point = new CvPoint;

//point->x = 1;
//point->y = 1;

//return point;

CvPoint point;
point.x = 1;
point.y = 1;
return &point;

}


int _tmain(int argc, _TCHAR* argv[])
{
CvPoint *testpointer;

testpointer = testPointer();

cout<<"testpointer->x:"<<testpointer->x<<endl;//这里还能再访问一次

cout<<"(*testpointer).x:"<<(*testpointer).x<<endl;
cout<<"testpointer->x:"<<testpointer->x<<endl;
system("pause");
return 0;
} C++;C;作用域
[解决办法]
方法里是结束了。但是有新变量在引用
[解决办法]
函数的局部变量定义在函数的栈上 函数退出时析构。new的空间定义在堆上。函数退出时还在。
void testVar()
{
Point* ptr = new Point[100];
}
ptr变量(虽然是指针)定义在函数testVar栈上,函数退出时,改指针被销毁。
ptr指向的空间是堆内存,当ptr被销毁则这块内存始终得不到释放,内存泄露。。。
分清楚指针变量和指针指向的内存。


[解决办法]
这样的写法的确是有问题的,在离开函数的时候的确被析构了,理论上是不能再访问的,但是实际上系统回收空间是需要一定时间的,这里说的不是析构的问题,而是析构后的一些善后,这个你不需要了解,不要这么用就好了

如果是用你注释掉的方法的话,new出来的数据是分配在堆上的,的确不会被析构,但是会有其他问题,容易造成内存泄漏。具体可以看看《effective C++》的条款23: 必须返回一个对象时不要试图返回一个引用,这里有提到new的问题。一般除了某些情况,尽可能返回对象的copy比较好,也就是说传递参数可以用引用、指针,返回时尽量返回对象本身。虽然会造成copy,但是一般会减少不必要的麻烦(内存泄漏什么的)。
[解决办法]
你这里也没有构造析构的问题,
class CvPoint
{
public:
int x;
int y;
};


struct CvPoint
{
int x;
int y;
};
效果一致,是一种POD数据类型。
构造,析构都是什么也不做。

已被回收的内存,也是可以使用的,
使用以后出错,就纯粹是你自己的问题了;

系统可以保证,自身没有出错就行。

C,C++ 从来就没有说,错误的方法,就一定会出错。
只是系统不能保证,不会出错。

保证程序的正确性,是程序员自己的责任。

系统只是提供各种便利而已。









读书人网 >C++

热点推荐