C语言基础-动态内存分配
11.1 动态内存分配
数组被声明时,必须要在编译时知道它的长度。
动态分配内存允许程序为一个长度在运行时才知道的数组分配内存空间。
11.2 malloc&free
C语言函数库提供了malloc和free两个函数,分别执行动态内存的分配和释放。这些函数维护一个可用的内存池。
原型分别为:
void *malloc( size_t size );
void free( void *pointer );
- 调用malloc函数时,malloc从内存池中提取一块合适的内存,并返回一个这块内存的指针。
这块内存并没有以任何的方式进行初始化。可以手动初始化。
如果内存无法满足需求,返回一个NULL指针。因此每次对malloc返回的指针进行检查是否非NULL非常重要。 - free函数释放内存空间。free的参数必须是NULL指针或者先前从malloc,calloc,realloc返回的指针。
- malloc并不知道所请求的内存是需要存储什么类型。所以malloc返回一个void * 的指针。
*标准表示一个void 的指针可以转换为其他任何类型的指针。 - 对于有边界对齐的机器,malloc 所返回的内存的起始位置将时钟能够满足对边界对齐要求最严格的类型要求。
11.3 calloc&realloc
原型分别为:
void *calloc( size_t num_elements, size_t element_size );
void realloc( void *ptr, size_t new_size );
- calloc函数 在返回指向内存指针之前把它初始化为0。如果只是像存储一些值到数组中,就不必要初始化,而使用malloc函数。
- calloc 的参数包括需要元素的数量和每个元素的字节数。
- realloc 用于修改原先已经分配好的内存块的大小。可扩大,可缩小。
如果原来的内存块无法改变大小,realloc将分配一个正确的内存大小,并把原来的内容复制到新的内存块。
因此,在使用realloc 函数之后,就不能使用指向旧内存的指针,改用realloc 返回的指针。
举例:
int *pi;
pi = malloc( 25 * sizeof( int ) ); //或者 pi = malloc( 100 );
if( pi == NULL ){
print( "out of memory!\n" );
exit(1);
}
/*
通过下标引用初始化数组元素为 0
*/
int i;
for( i = 0; i < 25; i++) pi[i] = 0;
/*
通过指针间接访问初始化数组元素为0
*/
int *p;
p = pi;
for( i = 0; i < 25; i++ ){
*p++ = 0;
}
注意1: 不要访问已经被free函数释放的内存.
假如对指向动态分配的内存的指针进行了复制,这些指针散落在程序各处,必须保证使用这个内存的地方在内存被释放前停止使用这块内存。
注意2: 对内存进行操作时,一定要注意边界,超过边界会造成不可预知的后果。
注意3: 每次malloc后,一定要检查内存是否分配成功。
注意4: 当内存不被使用时,一定要释放,否则会造成内存泄漏,内存被使用完。可能导致当前已经完成的工作全部丢失。
实例:
/*
alloc.h,头文件
定义一个不易发生错误的内存分配器接口
*/
#include <stdlib.h>
#define malloc //不要直接条用malloc,要使用malloc,必须先#undef malloc;直接使用编译器会报错。
#define MALLOC(num,type) (type *)alloc( (num) * sizeof( type) )
extern void *alloc( size_t size );
/*
alloc.c
不易发生错误的内存分配器实现
*/
#include <stdio.h>
#include "alloc.h"
#undef malloc
void *alloc( size_t size )
{
void *new_mem;
new_mem = malloc( size );
if( new_mem == NULL ){
print( "out of memory!\n" );
exit(1);
}
return new_mem;
}
/*
使用错误检查分配器
*/
#include "alloc.h"
void function()
{
int *new_mem;
new_mem = MALLOC( 25, int );
}
浙公网安备 33010602011771号