使用new运算符分配的内存与通过简单变量声明(如int var )分配的内存之间有哪些技术差异?c++有任何形式的自动内存管理吗?
特别是,我有几个问题。首先,对于动态内存,您必须声明一个指针来存储您使用的实际内存的地址,所以动态内存不需要更多的内存吗?我不明白为什么指针是必要的,除非您声明一个数组。
第二,如果我要做这样一个简单的功能:
int myfunc() { int x= 2;int y= 3;返回x+y;}
...And调用它时,函数分配的内存会在其存在范围结束后立即释放吗?动态记忆呢?
发布于 2009-06-20 09:00:37
注:这个答案太长了。我什么时候会把它剪下来的。同时,评论如果你能想到有用的编辑。
为了回答您的问题,我们首先需要定义两个内存区域,称为堆栈和堆。
堆叠
把堆栈想象成一堆盒子。每个框表示函数的执行。一开始,当main被调用时,地板上有一个盒子。您定义的任何局部变量都在该框中。
一个简单的例子
int main(int argc, char * argv[])
{
int a = 3;
int b = 4;
return a + b;
}在本例中,在地板上有一个带有变量argc (整数)、argv (指向char数组的指针)、a (整数)和b (整数)的框。
不止一个盒子
int main(int argc, char * argv[])
{
int a = 3;
int b = 4;
return do_stuff(a, b);
}
int do_stuff(int a, int b)
{
int c = a + b;
c++;
return c;
}现在,在地板上有一个盒子(用于main),上面有argc、argv、a和b。在该框的顶部,还有另一个框(用于do_stuff),其中包含a、b和c。
这个例子说明了两个有趣的效果。
你可能知道,
b是按值传递的.这就是为什么do_stuff.free或delete,也不需要这些变量的任何内容。当函数返回时,该函数的框将被销毁。箱溢出
int main(int argc, char * argv[])
{
int a = 3;
int b = 4;
return do_stuff(a, b);
}
int do_stuff(int a, int b)
{
return do_stuff(a, b);
}在这里,您在地板上有一个盒子(用于main,和以前一样)。然后,您有一个带有a和b的框(用于b)。然后,您有另一个框(用于do_stuff调用自身),同样带有a和b。然后又是另一个。很快,就会有堆栈溢出。
堆栈摘要
把堆栈想象成一堆盒子。每个框表示正在执行的函数,该框包含在该函数中定义的局部变量。当函数返回时,该框将被销毁。
更多技术性的东西
堆
这就是动态内存分配发挥作用的地方。
把这堆想象成一片永无止境的绿色记忆草地。调用malloc或new时,会在堆中分配一个内存块。您将获得一个访问此内存块的指针。
int main(int argc, char * argv[])
{
int * a = new int;
return *a;
}这里,在堆上分配一个新整数的内存值。您将得到一个名为a的指针,该指针指向该内存。
a是局部变量,在main的"box"中也是如此。
动态内存分配原理
当然,使用动态分配的内存似乎会在指针上浪费几个字节。但是,没有动态内存分配,有些事情(很容易)是做不到的。
返回数组
int main(int argc, char * argv[])
{
int * intarray = create_array();
return intarray[0];
}
int * create_array()
{
int intarray[5];
intarray[0] = 0;
return intarray;
}这里发生了什么?您可以在create_array中“返回一个数组”。实际上,您返回一个指针,它只指向包含数组的create_array“框”的部分。当create_array返回时会发生什么?它的盒子被破坏了,你可以期望你的数组在任何时候都会被破坏。
相反,使用动态分配的内存。
int main(int argc, char * argv[])
{
int * intarray = create_array();
int return_value = intarray[0];
delete[] intarray;
return return_value;
}
int * create_array()
{
int * intarray = new int[5];
intarray[0] = 0;
return intarray;
}因为函数返回不会修改堆,所以您宝贵的intarray将不受损害地转义。但是,请记住,在您完成之后,delete[]它。
发布于 2009-06-20 07:26:00
动态内存存在于堆上,而不是堆栈上。动态内存的生命周期是从分配时间到取消分配时间。对于局部变量,它们的生存期仅限于在其中定义的函数/块。
关于函数中内存使用的问题,在您的示例中,局部变量的内存将在函数的末尾释放。但是,如果使用new动态分配内存,则不会自动释放内存,您将负责显式地使用delete释放内存。
关于自动内存管理,C++标准库为此提供了auto_ptr。
发布于 2009-06-20 07:26:06
由"new“分配的内存将在堆上结束。
在函数中分配的内存驻留在函数中,函数放在堆栈上。
在这里阅读有关堆栈和堆分配的信息:http://www-ee.eng.hawaii.edu/~tep/EE160/Book/chap14/subsection2.1.1.8.html
https://stackoverflow.com/questions/1021138
复制相似问题