在程序的执行期间分配内存时,内存区域中的这个空间称为堆(heap)。还有另一个内存
区域,称为堆栈(stack),其中的空间分配给函数的参数和本地变量。在执行完函数后,存储
参数和本地变量的内存空间就会释放。堆中的内存是由程序员控制的。
malloc():
int *pNumber = (int*)malloc(100); // 分配100字节内存
int *pNumber = (int*)malloc(25*sizeof(int)); //存储25个int值得内存
类型转换(int*)将函数返回的地址转换成 int 类型的指针。malloc()返回 void 类型的指针,
void* 可以指向任何类型的数据,不能取消对 void 指针的引用,因为它指向未具体说明的对象。
如果因某种原因而不能分配请求的内存,malloc()会返回一个 NULL 指针。
用 if 语句检查是否分配:
int *pNumber = (int*)malloc(25*sizeof(int));
if (!pNumber)
{
// 内存分配失败的处理代码
}
释放动态分配的内存:
free(pNumber);
pNumber = NULL;
colloc() :
与 malloc() 相比有两个优点:
(1)它把内存分配为给定大小的数组;
(2)它初始化了所分配的内存,所有位都是 0。
int *pNumber = (int*)calloc(75, sizeof(int));
// 分配了包含75个int元素的数组
如果不能分配所请求的内存,返回值就是 NULL。
可以让编译器执行类型转换:
int *pNumber = calloc(75, sizeof(int));
扩展动态分配的内存 realloc() :
realloc() 函数可以重用或扩展以前用 malloc()或 calloc()(或者realloc())分配的内存。
realloc()的两个参数:
1)、一个是包含地址的指针,该地址以前由malloc()、colloc()或realloc()返回。
2)、要分配的新内存的字节数。
realloc()函数分配第二个参数指定的内存量,把第一个指针参数引用的、以前分
配的内存内容传递到新分配的内存中,传递的内容量是新旧内存中区域较小的那一个。
realloc()函数返回一个指向新内存的void*指针,如果分配失败,返回NULL。如果
第一个参数是NULL,就分配第二个参数指定的新内存,类似malloc()。
realloc()保存了原内存区域的内容,且保存的量是新旧内存区域中较小的那个。
如果新内存区域大于旧内存区域,新增的内存就不会初始化,而是包含垃圾值。
动态分配内存的基本原则 :
* 避免分配大量的小内存块。分配堆上的内存有一些系统开销,所以分配许多小的内存块
比分配几个大内存块的系统开销大。
* 仅在需要时分配内存。只要使用完堆上的内存块,就释放它。
* 总是确保释放以分配的内存。在编写分配内存的代码时,就要确定在代码的什么地方
释放内存。
* 在释放内存之前,确保不会无意中覆盖堆上已分配的内存地址,否则程序就会出现内存
泄漏。在循环中分配内存时,要特别小心。