创建和处理动态数据结构需要用到动态内存分配。理论上可以分配到的内存空间的最大值是计算机中可用的物理内存总量或虚拟存储系统中可用的虚拟内存总。由于内存要被多个应用程序分享,大多数情况下可以分配到的最大内存空间往往要比理论值小得多。
malloc和free以及sizeof是实现动态内存分配的基础。
malloc
函数malloc以请求分配的字节数为实参,返回一个指向分配到的内存空间的首地址,类型为void * 的指针(可以被赋值给任意类型的指针变量),常与sizeof运算符配合使用。如下:
struct node {
int data;
struct node * next;
};
struct node * newPtr = malloc(sizeof(struct node));
上述语句首先计算表达式sizeof(struct node)的值,以确定类型为struct node的结构体占用空间的大小(以字节为单位),然后申请这样字节大小的一块内存区域,并将指向这块内存区域的指针赋给指针变量newPtr。注意,分配到的内存是未经过初始化的。如果没有可以分配的内存,则malloc返回NULL。使用malloc时一定要测试其返回值是否为NULL。
free
函数free的功能是释放内存空间,即将内存空间返还给系统。这样就可以在将来某个时间被系统重新分配。使用如下:
free(newPtr);
当动态分配来的空间不再被需要时,应用free将其返还给系统,如未将其返还给系统,将可能导致系统内存空间过早耗尽,这个错误有时被称为内存泄露(memory leak)。而释放了非动态分配而来的内存空间则是一个错误。若访问了被释放了的内存空间会导致程序崩溃。
calloc
函数calloc原型是:
void *calloc(size_t nmemb, size_t size);
nmemb表示数组元素的个数和size表示数组元素大小,指向由calloc申请的一段连续的内存空间的指针就可以被当做一个数组下标使用,calloc同时将数组的每一个元素都初始化为0。如果申请成功,函数calloc返回一个指向申请到的内存空间的指针,否则返回一个NULL指针。函数calloc与malloc最根本的差别是calloc会清空其申请到的内存空间,而malloc不会。
realloc
用来改变先前调用函数malloc,calloc或者realloc申请到的一个对象的大小。如果新申请到的内存的容量大于原先申请到的内存,则原先对象的内容不会被修改。否则,只有不超过新对象大小内容不会被修改。函数原型为:
void *realloc(void *ptr, size_t size);
其中两个实参ptr为指向原先对象的指针,size为这个对象的新的长度。如果ptr为NULL,则realloc与malloc功能相同。如果size为0,而ptr不为NULL,则ptr所指的内存空间将会被释放。如果ptr不为NULL,而size大于0,则函数realloc将试图为其申请一块新的内存空间。如果申请失败,则ptr指向的对象不会被修改。函数realloc要么返回一个指向新申请到的内存空间的指针,要么返回一个NULL指针表示申请失败。