当前位置:文档之家› 动态内存分配

动态内存分配

一、malloc和free
1.c函数库提供了两个函数,malloc和free,分别用于执行动态内存分配和释放。这些函数维护一个可用内存。
2.当一个程序另外需要一些内存时,它就调用malloc函数,malloc从内存池中提取一块合适的内存。并向该程序返回一个指向这块内存的指针。这块内存此时并没有以任何方式进行初始化。如果要对其进行初始化,要么自己动手进行初始化,要么使用calloc()函数。当一块以前分配的内存不在使用时,程序调用free函数把它归还给内存池供以后使用。
3.这两个函数的原型如下,都在头文件stdlib.h中声明
1>void *malloc(size_t size);
2>void free(void *pointer);
4.malloc的参数就是需要分配的内存字节数。如果内存池中的可用内存可以满足这个需求,malloc就返回一个指向被分配的内存块起始位置的指针。
1>malloc所分配的是一块连续的内存。例如:如果请求分配100个字节的内存,那么它实际分配的内存就是100个连续的字节,并不会分开位于两块或多块不同的内存。同时,malloc实际分配的内存有可能比你请求的稍微多一点。但是这时由编译器定义的。
2>如果内存池是空的,或者它的可用内存无法满足要求时。在该情况下,malloc()函数向操作系统请求,要求得到更多地内存,并在这块内存上执行分配任务。如果操作系统无法向malloc提供更多的内存,malloc就返回一个NULL指针。因此,要对每个从malloc返回的指针都进行检查,确保它并非NULL是非常重要的。
5.free的参数必须要么是NULL,要么是一个先前从malloc,calloc或realloc返回的数值。想free传递一个NULL参数不会产生任何效果。
6.malloc并不知道请求的内存需要存储的是整型、浮点值、结构还是数组。Malloc返回一个类型为void *的指针。在标准中表示一个void *类型的指针可以转换为其他任何类型的指针。因此,在使用前,要进行强制类型转换。

二、calloc和realloc
1.还有两个内存分配函数,calloc和realloc。它们的原型如下:
void *calloc(size_t num_elements,size_t element_size);
void realloc(void *ptr,size_t new_size);
2.calloc也用于分配内存。malloc和calloc之间的区别是后者在返回指向内存的指针之前把它初始化为0。但如果程序只是想把一些值存储到数组中,那么这个初始化过程纯属浪费时间。
3.calloc和malloc之间另一个较小的区别是它们请求内存数量的方式不同。calloc的参数包括所需元素的数量和每个元素的字节数。根据这些值,它能够计算出总共需要分配的内存。
4.realloc函数用于修改一个原先已经分配的内存块大小。
1>使用这个函数,你可以使一块内存扩大或缩小。如果它用于扩大一个内存块,那么这块内存原先的内

容依然保留,新增加的内存添加到原先内存块的后面,新内存并未以任何方法进行初始化。
2>如果它用于缩小一块内存块,该内存块尾部的部分内存便被拿掉,剩余部分内存的原先内容依然保留。
3>如果原先的内存块无法改变大小,realloc将分配另一块正确大小的内存,并把原先那块内存的内容复制到新的块上。因此,在使用realloc之后,就不能再使用指向旧内存的指针,而是应该该用realloc所返回的新指针。
4>如果realloc函数的第一个参数是NULL,那么它的行为就和malloc一模一样。

三、常见的动态内存错误
1.使用动态内存分配的程序中,常常会出现很多错误。
1>对NULL指针进行解引用操作
2>对分配的内存进行操作时越过边界
3>释放并非动态分配的内存
4>试图释放一块动态分配的内存的一部分以及一块内存被释放之后被继续使用。
说明:
1.动态分配最常见的错误就是忘记检查所请求的内存是否成功分配。
2.动态内存分配的第二大错误来源是操作内存时超出了分配内存的边界。
3.当你使用free时,可能出现各种不同的错误。
1>传递给free的指针必须是一个从malloc、calloc或realloc函数返回的指针。
2>传递给free函数一个指针,让它释放一块并非动态分配的内存可能导致程序立即终止或在晚些时候终止。
3>试图释放一块动态分配内存的一部分也有可能引起类似问题。

总结:
1.当数组被声明时,必须在编译时知道它的长度。动态内存分配允许程序为一个长度在运行时才知道的数组分配内存空间。
2.malloc和calloc函数都用于动态分配一块内存,并返回一个指定该块内存的指针。
1>malloc的参数就是需要分配的内存的字节数。
2>calloc的参数是需要分配的元素个数和每个元素的长度。calloc函数在返回前把内存初始化为零。malloc函数返回时内存并未以任何方式进行初始化。
3>调用realloc函数可以改变一块已经动态分配的内存的大小。增加内存块大小有时有可能采取的方法是把原来内存块上的所有数据复制到一个新的、更大的内存块上。当一个动态分配的内存块不再使用时,应该调用free函数把它归还给可用内存池,内存释放后便不能再被访问。
3.如果请求的内存分配失败,malloc、malloc和readlloc函数返回的将是一个NULL指针。
4.错误的访问分配内存之外的区域所引起的后果类似越界访问一个数组,但这个错误还能破坏可用内存池,导致程序失败。
5.如果一个指针不是从早先的malloc、calloc或realloc函数返回的,它是不能作为参数传递给free函数的。

相关主题
文本预览
相关文档 最新文档