返回首页

介绍
这些文章的主要目的是教导新手如何在C代码中的内存泄漏的免费程序。
它已经很长一段时间,因为我写一个auto_ptr的文章的思想。当我开始学习auto_ptr的时,我发现许多文章描述auto_ptr的真的是,它们的用途是什么,以及如何使用它们的实现代码。要非常坦率,我could't发现这解释了深入auto_ptr的任何物品。最后,我决定写一篇文章,这将作为一个在网络上的文章的延伸。
开始auto_ptr的人会问的第一个明显的问题是什么是auto_ptr的。
自动指针船舶作为一个STL的标准命名空间的一部分。 auto_ptr是一个模板类,主要创建用于封装任何动态创建的对象,最好使用新营办商。自动指针的作为的免费存储中动态创建的对象的容器灾害,一旦你分配一个内存块你需要没有真正关心分配的内存,因为汽车的指针需要释放该内存区护理一次的封装对象去的范围,可能不会需要了。
让我们看看在下面的不安全的代码:




void myFunction()

{

	T* ptr = new T; 



	/*... code...*/ 



	delete ptr;

}




大多数人都喜欢我们写类似这样的日常代码,此代码将很好地工作,如果它没有做任何特殊。如果MyFunction的永远不会执行delete语句,要么是因为这将导致控制回去作为函数的返回结果,或者是因为函数执行期间抛出的异常的来电条件。这是一个理想的情况下,我们可以有一个经典的内存泄漏问题。
现在的第一个问题,会弹出在你的头脑是如何处理这种困难的情况下。这个问题的答案是自动指针,我们可以总结指针PTR宣布在上面的代码到一个智能指针,是自动指针对象和忘记的内存泄漏问题。现在,即使代码执行delete语句没有达到,我们可以确保内存指针变量指出被清理时,函数的堆栈开卷。
让我们看看在纠正myfunction的功能:{C}
在上面的代码,我们甚至不需要显式调用PTR所载指针删除。自动指针自动释放内存的关于销毁包含的对象。
使用一个auto_ptr只是使用内建指针相同,"收回"的资源,并承担再次手动所有权,我们只是调用release():
我们可以使用auto_ptr的reset()函数重置的auto_ptr自己不同的对象。如果的auto_ptr已经拥有的对象,但是,它已经拥有先删除对象,因此调用reset()破坏的auto_ptr,并创建一个新的,拥有新的对象:



void myFunction()

{

	auto_ptr ptr( new CMyClass(1) ); 



	ptr.reset( new CMyClass(2) );

	// deletes the first CMyClass that was

	// allocated with "new CMyClass (1)" 



} // finally, ptr goes out of scope and

// the second CMyClass is also deleted



Now comes the main part that I discussed in the begining of this article, I have not seen any real world example describing use of auto_ptr as a class level variable.



class CName

{

public:

	CName()

	{

		m_pName = NULL;

	}

	 CName()

	{

		delete[] m_pName;

	}

	void SetupName(int nSize)

	{

		m_pName = new char[nSize];

	}

	void SetName(char* pName)

	{

		strcpy(m_pName,pName);

	}

	char* GetName()

	{

		return m_pName;

	}

private:

	char* m_pName;

};



class CEmployee

{

public:

	CEmployee()

	{

		m_ptrName = new CName();

	}

	 CEmployee()

	{

		delete m_ptrName;

	}

	void Name(char* pName)

	{

		m_ptrName->SetName(pName);	// Runtime Exception: memory should have been 

						// allocated before setting name by using syntax

						// m_ptrName->SetupName(<size>);		

	}

	void PrintName()

	{

		printf("Name: %s\n",m_ptrName->GetName());

	}

private:

	CName* m_ptrName;

};



void myFunction()

{

	CEmployee objEmp;

	objEmp.Name("Neeraj"); // Exception 

	objEmp.PrintName();

}




上面的代码肯定会造成雇员的名义内存设置时,不分配调用SetupName功能的运行时异常。其一定的程序停止执行时发生异常,如果你发现在那里有一个经典的内存泄漏类CEmployee使用运营商在其构造新创建的CNAME的实例代码仔细。这种分配的内存永远不会被释放的代码执行从未达到最高这一点。当然,我们可以封装成一个auto_ptr对象CNAME的PTR内存分配异常安全的,下面的代码确保CEmployee类描绘了正确的代码。
上面的代码创建一个auto_ptr对象CEmployeeName类成员。通过这样做,我们将确保m_ptrName对象所包含的内存被释放了,即使发生异常的情况下。仔细看看构造函数析构函数,类的构造函数创建一个CNAME类的实例的所有权传递给类的成员CNAME auto_ptr的m_ptrName。在析构函数中,我们采取了auto_ptr的中CNAME类的指针的所有权,我们安全地调用delete删除。
当一个auto_ptr的所有权是从一个auto_ptr传递到另一个。如果左值auto_ptr对象已经包含了一个有效的PTR的auto_ptr首先释放内存,然后重视rvalue的指针。| Neeraj S

回答

评论会员:游客 时间:2011/12/16
提供这么好的article.Will您提供更多的例子使用Boost库的智能指针感谢..感谢..
levi13
评论会员:游客 时间:2011/12/16
//传递所有权的一个auto_ptr{BR}codepreauto_ptrptr2(ptr1);/pre/code不应该写成//通过所有权,一个auto_ptrcodepreauto_ptr<cmyclass>ptr2(ptr1);/pre/code