它是什么
----------
动态分配是 C/C++ 中内存的自动分配。与将数据加载到程序的数据段的声明不同,动态分配会在程序的堆栈(分配给该程序的特定 RAM 区域)上创建新的可用空间。
它通过两个函数(C 中)和两个运算符(C++ 中)来实现
malloc 和 free,new 和 delete。
为什么使用它
--------------
动态分配可能非常有用。例如,一个动态大小的数组
假设 size 是一个变量(它不是定义为常量)。如果尝试这样做,编译器会报错
两个版本
您可以做的是动态分配此内存。例如
C 版本
1 2
|
int *array;
array=(int *) malloc(size*sizeof(int));
|
C++ 版本
1 2
|
int *array;
array=new int[size]l
|
注意
由于这些数据被推送到堆栈而不是段,因此存在内存泄漏的可能性。内存泄漏是指分配的内存未在程序返回之前释放。例如,要安全地释放刚创建的数组(并正常返回程序)
C 版本
C++ 版本
另一个特别的注意:delete 后面的括号只有在你最初分配了一个数组时才需要。
动态分配对于使用链表是必要的。假设已声明自引用的结构 Node,其中 nextptr 是链接
C 版本
1 2 3 4 5 6 7
|
struct Node *newptr;
newptr=(struct Node *) malloc(sizeof(Node));
/*We'll insert this into this linked list just
at the second item, assuming topptr is the name
of the top of this list.*/
newptr->nextptr=topptr->nextptr;
topptr->nextptr=newptr;
|
C++ 版本
1 2 3 4 5
|
Node *newptr;
newptr=new Node;
//We'll insert this as the second item, using topptr.
newptr->nextptr=topptr->nextptr;
topptr->nextptr=newptr;
|
当然,在以上两个示例中,结构 Node 中没有使用其他成员,这违背了链表的初衷。释放节点
C 版本
1 2 3 4 5 6 7
|
struct Node *tempptr;
/*The node we'll free is, again, the second.*/
tempptr=topptr->nextptr;
/*We'll unbind this node first, so as not to lose all of the rest of the list with it.*/
topptr->nextptr=tempptr->nextptr;
/*It's free, get rid of it.*/
free(tempptr);
|
C++ 版本
1 2 3 4 5 6 7
|
Node *tempptr;
//We'll get the second node again.
tempptr=topptr->nextptr;
//Unbind this node.
topptr->nextptr=tempptr->nextptr;
//Get rid of it.
delete tempptr;
|
如何使用它
-------------
C 函数的语法是
1 2 3
|
#include <stdlib.h>
void *malloc(size_t size)
|
前几个示例中的类型转换是必要的,因为 malloc 返回 void 指针。
1 2 3
|
#include <stdlib.h>
void free(void *);
|
这不需要类型转换;任何传递的参数都会被隐式降级。
C++ 中的运算符是
C++ 会自动为您进行类型转换。
1 2 3 4
|
//If this is an array
delete [] NewAlloc;
//Otherwise
delete NewAlloc;
|
更进一步
-------------
vector 和 list 等几个类使用了此功能。实现您自己的!
理解本文需要对指针和数组(及其关系)有深入的了解。我知道,我应该把这个放在最上面。
定义一个类(我将其命名为 SafeSpot),它将在对象销毁时自动处理其中定义的内存的释放。这将消除所有那些意想不到的内存泄漏。您可能希望为该类的不同分配范围尝试不同的范围(不要让临时函数对象存在于整个程序中)。
请回复,告诉我您对这篇文章的看法!
谢谢,
Graham Northup