Jun*_*ier 4 c++ memory free memory-management dynamic
我是一名C和Java程序员,因此内存分配和OOP对我来说并不是什么新鲜事.但是,我不确定如何使用C++实现对象来避免内存泄漏.即:
string s1("0123456789");
string s2 = s1.substr(0,3);
Run Code Online (Sandbox Code Playgroud)
s2 现在有一个新的字符串对象,所以它必须通过以下方式释放:
delete &s2;
Run Code Online (Sandbox Code Playgroud)
对?
此外,我是否正确地假设我将不得不删除函数返回的任何(新)对象的地址,无论返回类型不是指针或引用?生活在堆上的对象在必须被释放时不会作为指针返回,这似乎很奇怪.
答案有几层.
首先,变量可以用几种不同的方式声明:
int i,或int i = 42.它们具有自动存储持续时间(这些示例在技术上是简写auto int i,或者auto int i = 42,尽管auto关键字实际上从未使用过.这意味着这些变量在超出范围时将自动释放.它们的析构函数保证被调用(不无论你如何离开范围,无论是通过函数返回还是抛出异常,它们的析构函数将在它们超出范围时被调用,然后它们使用的内存被释放..这样声明的局部变量被分配在堆栈.static关键字,暗示静态存储持续时间,而不是上面显示的自动.这些只是在程序的持续时间内保持不变,因此不必释放new int或new int(42)).这些必须通过调用手动释放delete.所以在最低级别,你基本上只需保持对称性.如果分配了一些东西new,可以使用delete,malloc is freed byfree , andnew [] bydelete []` 释放它.并且没有任何这些声明的变量会自动处理,不应手动释放.
现在,为了简化内存管理,通常使用RAII.该技术基于以下观察:只有动态分配的对象必须手动释放,并且局部变量为您提供了一个非常方便的钩子,用于在局部变量超出范围时实现自定义操作.
因此,动态分配包含在一个单独的类中,可以将其分配为堆栈中的本地对象.然后,它可以在其构造函数中进行所需的任何动态分配,并且它的析构函数会使用必要的delete调用来清理它.
这意味着你实际上从未有打电话给delete你的顶级代码.它几乎总是隐藏在RAII对象的析构函数后面.new调用变得罕见,但仍然与智能指针一起使用(例如:boost::shared_ptr<int>(new int(42))它动态分配一个整数,然后将其传递给智能指针,该指针接管它的所有权,并自动清理它.
s1和s2都是自动分配的.你不删除它们.您只能delete使用您创建的对象new.
C++知道三种分配模式:自动,静态和动态.阅读这些内容.自动值(如示例中的字符串)在离开作用域时会自动释放.他们的析构函数会自动调用.调用字符串析构函数时,将释放在操作期间动态分配的字符串的任何内存.