<C和指针---读书笔记14>
动态内存分配
为什么需要动态分配内存?
首先硬件的内存是有大小限制的,如果软件太过于复杂,会使得内存逐渐用满。所以需要我们不时的释放内存。
当我们声明一个数组,用于存放 : 用户输入信息时。 这是就很尴尬了,到底声明多大的? 太小的话怕溢出,太大的话怕
浪费。最好的方法:用户先输入信息,软件时刻更新长度信息。敲入回车后,声明一个大小恰巧的数组,并把 输入信息填入。
malloc 和Free
这两个是库函数stdlib.h里面封装的函数。用于分配内存字节、和释放内存。
void *malloc ( size )
参数列表: size ,代表要分配的内存bytes数目。
返回值: 返回一个指针,它可以赋值给其他指针变量。
功能 : 程序运行过程中,自动的分配 size 个 bytes数目。 但并不会对这些内存进行初始化赋值,它们仍保留原值。
并且,它分配的内存是连续的 size个。如果内存池能够满足要求,就返回一个指针,该指针指向被分配内存
单元的起始位置。如果内存池里面无法满足这个要求时,就返回一个NULL指针。
因此,对 malloc 的返回值检查将十分重要。
事例 :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
main(){
int *pi = NULL;
int i;
pi = malloc( 25 * sizeof(int));
if( pi == NULL ) {
printf("Quit\r\n");
}
else {
printf("%d\r\n",pi);
for(i =0 ; i<100 ;i++) {
pi[i] = i ;
}
}
printf("%d\r\n",pi[0]);
printf("%d\r\n",pi[1]);
printf("%d\r\n",pi[24]);
}
分配空间时,使用 25 *sizeof(int) 总共分配 100个 byte 。 先判断是否返回NULL。 然后对其初始化。我们使用 pi[0]的形式,避免使用 *pi++ 修改pi的值。
void free ( void *point )
参数列表:一个指针。指向被释放的起始地址。 且这个指针必须是 malloc函数返回的指针。
返回值: void
功能 : 释放内存给内存池。 内部具体如何动作的,如何知道释放内存长度的,我现在还不知道。
事例 : free(pi)
calloc 和 realloc
除了刚才刚用的两个 malloc和free函数外,还有两个关于内存分配的函数,他们也封装在 stdlib.h里面。
void * calloc(num_element , elemet size);
参数列表:元素个数,以及每个元素的大小, 即分配的总长度为 num*size 个bytes
返回值: 返回一个指针,指向起始位置。
功能 : 跟malloc一样,分配若干个内存空间。 不同之处在于 : 分配同时并进行了clr行为,即全部清零操作。
事例 : ---
void * realloc( *ptr , new_size) ;
参数列表:原指针。新的大小。
返回值: 返回一个指针,指向起始位置。
功能 : realloc首先判断 ptr是否为NULL,若为NULL, 就等价于 mallco(new_size).
如果不为NULL,此时可能会有两种情况 ---- new_size大于原来的.或者小于原来的。
new_size小于old_size的话, 直接砍掉尾部,保留头部.
new_size大于原来old_size时:还要继续看尾部是否有足够空间能容下 new-old。
如果能容下,就直接在尾部补充. 返回一个指针.
如果不能,就重新在内存池中找一个地方,重新malloc(new_size),并把原来的内容搬迁过去.
返回一个新的起始地址. 此时旧的指针就成了野指针了,需要做NULL处理.
事例 : ---
常见动态内存错误
自己都没怎么写过 动态分配的例子,就不班门弄斧了.