我们使用数组时,它是存储于内存中连续的位置上,它所需要的内存在编译时就被分配,使用起来比较方便,但是也存在几个缺点。
数组的缺点:
1)假如一个数组无限大,而我们只需要很少的几个字节,这就会造成内存浪费,增加了内存的开销。
2)我们我们访问超过数组下标的内容时,造成数组越界,有可能产生一个异常值,从而导致失败。
针对这两点,动态内存分配的处理就相对比较适用。动态内存分配中使用的几个关键字
malloc和free,这两个是成对出现的,malloc用来申请内存空间,free用来释放内存。
malloc和free
malloc从内存池中提取一块合适的内存,并向该程序返回一个指向这块内存的指针。这块内存没有初始化。
当内存不再使用时,调用free把这块内存归还给内存池。
原型:
void malloc(size_t size);
void free(void pointer);
malloc的参数是需要分配的内存字节数。
malloc分配的是一块连续的内存。如果请求分配的是100个字节,那么实际分配的就是100个连续的字节,不会分开于两块或多块不同的内存。
如果内存池为空,或者申请内存不成功,malloc就会返回一个NULL指针。如果需要对分配的内存进行检查,可以通过与NULL指针进行比较来判断内存是否分配成功。
free的参数必须是从malloc、calloc或relloc返回的值,或者是NULL。传递NULL指针不会产生任何效果。
例:1
2
3
4
5
6
7
8
9
10
11int *a;
...
a = malloc(100); //申请内存空间
memset(a,0x0,100); //清空内存
if (a == NULL) //判断内存是否申请成功
{
printf(“out of memory!\n”);
return ;
}
free(a); //释放内存
calloc和relloc
原型:
void calloc(size_t num_elements, size_t element_size);
void realloc(void ptr,size_t new_size);
calloc用于内存的申请。
calloc与malloc之间的主要区别是calloc在返回指向内存的指针之前把它初始化为0。但是如果你的程序知识想把一些值存储到数组中,那么这个初始化过程纯属浪费时间。
relloc函数用于修改一个原先已经分配的内存块大小。使用这个函数,你可以使一块内存扩大或缩小。如果它用于扩大一个内存块,那么这块内存原先的内容依然保留,新增加的内存添加到原先内存块的后面,新的内存并未以任何方式进行初始化。该内存块尾部的部分内存便被拿掉,剩余部分内存的原先内容依然被保留。
如果realloc函数的第1个参数是NULL,那么它的行为就和malloc一样。
内存泄漏:
当动态分配的内存不再需要使用时,它应该被释放。如果内存不释放,将会引起内存泄漏。内存泄漏可以一点点的榨干可用内存,从而导致程序崩溃。