C/C++ 语言系列(十二)动态内存分配与回收
C 语言
C++ integrates the operators
new
anddelete
for allocating dynamic memory. But these were not available in the C language; instead, it used a library solution, with the functionsmalloc
,calloc
,realloc
andfree
, defined in the header<cstdlib>
(known as<stdlib.h>
in C). The functions are also available in C++ and can also be used to allocate and deallocate dynamic memory.Note, though, that the memory blocks allocated by these functions are not necessarily compatible with those returned by
new
, so they should not be mixed; each one should be handled with its own set of functions or operators.
动态内存分配 malloc, calloc, realloc
https://www.runoob.com/cprogramming/c-memory-management.html
动态内存回收 free
https://www.runoob.com/cprogramming/c-memory-management.html
C++ 语言
动态内存分配 new
在 C++ 中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆内存(memory heap),这会返回所分配的空间地址。
动态内存分配使用 new
运算符,后面跟上一个数据类型,语法如下:
1 | // allocate memory to contain one single element of specified type |
例如:
1 | int * bar = new int(5); // int bar = 5 |
In this case, the system dynamically allocates space for five elements of type
int
and returns a pointer to the first element of the sequence, which is assigned tofoo
(a pointer). Therefore,foo
now points to a valid block of memory with space for five elements of typeint
.Here,
foo
is a pointer, and thus, the first element pointed to byfoo
can be accessed either with the expressionfoo[0]
or the expression*foo
(both are equivalent). The second element can be accessed either withfoo[1]
or*(foo+1)
, and so on…
由于使用动态内存分配机制,因此 number_of_elements
可以是一个变量,变量值在运行时才决定,例如:p = new int[i];
。
声明普通数组与使用 new
分配动态内存的区别:
There is a substantial difference between declaring a normal array and allocating dynamic memory for a block of memory using
new
. The most important difference is that the size of a regular array needs to be a constant expression, and thus its size has to be determined at the moment of designing the program, before it is run, whereas the dynamic memory allocation performed bynew
allows to assign memory during runtime using any variable value as size.
C++ 提供了两种标准机制来检查堆内存分配是否成功:
The dynamic memory requested by our program is allocated by the system from the memory heap. However, computer memory is a limited resource, and it can be exhausted. Therefore, there are no guarantees that all requests to allocate memory using operator
new
are going to be granted by the system.C++ provides two standard mechanisms to check if the allocation was successful:
机制一:异常机制
One is by handling exceptions. Using this method, an exception of type
bad_alloc
is thrown when the allocation fails. If this exception is thrown and it is not handled by a specific handler, the program execution is terminated.
1 foo = new int [5]; // if allocation fails, an exception is thrown
机制二:返回空指针
The other method is known as
nothrow
, and what happens when it is used is that when a memory allocation fails, instead of throwing abad_alloc
exception or terminating the program, the pointer returned bynew
is a null pointer, and the program continues its execution normally.This method can be specified by using a special object called
nothrow
, declared in header<new>
, as argument fornew
:
1 foo = new (nothrow) int [5];In this case, if the allocation of this block of memory fails, the failure can be detected by checking if
foo
is a null pointer:
1
2
3
4
5 int * foo;
foo = new (nothrow) int [5];
if (foo == nullptr) {
// error assigning memory. Take measures.
}This
nothrow
method is likely to produce less efficient code than exceptions, since it implies explicitly checking the pointer value returned after each and every allocation. Therefore, the exception mechanism is generally preferred, at least for critical allocations. Butnothrow
mechanism is more simplicity.It is considered good practice for programs to always be able to handle failures to allocate memory, either by checking the pointer value (if
nothrow
) or by catching the proper exception.
动态内存回收 delete
如果您不再需要动态分配的内存空间,可以使用 delete
运算符,删除之前由 new
运算符分配的堆内存(memory heap),以便该内存可再次用于其它动态内存分配。语法如下:
1 | // releases the memory of a single element allocated using new |