我已经在互联网上搜索了几个小时,并提出了这些步骤以防止内存泄漏(不使用智能指针和高级工具)。如果以下任何一项调查结果有任何问题,请通知我......提前致谢。
ex 1.
char *ptr;
ptr = new char[size];
// Some Code here
delete ptr;
前2。
//foo.h
class foo {
private:
char * ptr;
public
foo();
~foo();
};
// foo.cpp
foo::foo()
{
ptr = new char[100];
for (int i = 0; i < 100; i++)
ptr[i] = i;
}
foo::~foo()
{
delete ptr;
}
前3。
//main.cpp foo class stays the same as ex 2.
int main()
{
foo obj = new foo();
// Some code here
delete obj;
return 0;
}
前4。
//foo.h
class foo {
private:
char ** ptr;
public
foo();
~foo();
};
//foo.cpp
foo::foo()
{
ptr = new char[100];
for (int i = 0; i < 100; i++)
ptr[i] = new char[100];
for (int i = 0; i < 100; i++)
for (int j = 0; j < 100; j++)
ptr[i][j] = i;
}
foo::~foo()
{
for (int i = 0; i < 100; i++)
delete ptr[i];
delete ptr;
}
答案 0 :(得分:4)
以下是您自行管理内存时需要注意的一些提示: -
首先也是最重要的是: -
1)始终使用delete with new和delete [] with new []。混合这些将导致未定义的行为。
2)永远不要组合malloc / delete OR new / free。
对于您的问题“如果您有多维动态数组,则必须删除这两个级别。” 是的,你必须照顾他们。
你提到的事情是正确的,你必须在堆中分配内存时明确删除内存。虽然你错过了围绕RAII的一个重要方面。假设您正在处理分配/解除分配的功能。
void fun ()
{
1) int* ptr;
2) ptr = new int; //allocated memory.
3) ... //do something with ptr.
4) delete ptr; //done with ptr now delete it.
}
现在你通过删除使用new分配的内存来做得很好。但是,程序执行可能甚至无法达到您的删除。 (如果在STEP#3中抛出异常)。那种情况会造成内存泄漏。
为了解决这些问题,我们根据RAII的概念提供了智能指针。每当超出范围时,他们将自动删除他们所指的内存,这意味着您不需要处理内存管理。
答案 1 :(得分:1)
- 对于每个新的应该有一个删除。
醇>
是。更确切地说:每个new
必须匹配delete
,并且每个new[]
必须匹配delete[]
- 如果new在一个类中,将delete放入析构函数中则会处理动态分配的内存。
醇>
不!除非您明确禁止这些操作,否则您还应注意通过复制构造函数或赋值对副本执行的操作。有关详细信息,请参阅What is The Rule of Three?。
- 如果你在main中的类foo中执行一个新对象obj,那么你必须明确地删除obj。
醇>
??见1.?
- 如果您有多维动态数组,则必须删除这两个级别。 (我有点不确定这是安全的...我认为只有一个ptr的删除可能会这样做但是在思考之后我认为它是一个动态数组的动态数组,应该将它们分别视为一个动态数组。) / LI> 醇>
是的,如果您使用原始指针,无论有多少级别的间接,您都必须注意正确的内存管理。
我的最后建议是,保持头脑清醒,不必担心这些问题,但请使用<memory>
智能指针提供的内容和standard c++ containers。
请勿直接使用new
/ delete
,除非您100%确定自己正在做的事情,并确保200%的确定你真的需要这样做。
当您询问实际问题时:
(例2.)delete
与new char[]
ptr = new char[100];
// ^^^^^
foo::~foo() {
delete [] ptr;
// ^^ put the square brackets there
}
相同(例如4)