day24 动态内存申请

1.为啥动态申请内存?
我们通常数组大小是已知的,若所需内存空间取决于实际输入的数据,无法预先确定;需要动态分配内存;
静态分配:一般以数组形式,前提已知所需空间大小,分配在栈区或全局区;
动态分配:根据需要大小自由分配,按需分配,在堆区;
2.动态申请函数
包含在stlib.h头文件中
1)malloc函数

void *malloc(unsigned int size);

注:在调用malloc之后,一定要判断一下,是否申请内存成功;
多次申请,第一次和第二次申请内存不一定连续;
必须释放;

 char *p =(char *)malloc(100);
 free(p);

free后,p还是指向原先动态申请的内存,但是已经不能用了,p是野指针了·; 同一块内存只能释放一次;
2)calloc函数

void * calloc(size_t nmemb,size_t size);

申请nmemb块,每块的大小为size个字节的连续区域;

char *p(char *)calloc(3,100);//在堆区申请3块,每块大小100个字节,即300个连续的区域;

重点!!!!! malloc申请的内存,内存中存放的内容是随机的,不确定的,而calloc函数申请的内存中的内容为空;

3)realloc函数 重新申请内存
调用malloc 和calloc函数,单次申请的内存是连续的,两次申请的两块内存不一定连续;比如我先用malloc或者calloc申请了一块内存,我还想再原先内存的基础上挨着继续申请内存,或者我开始使用malloc或calloc申请了一块内存,我想释放后边的一部分内存,为了解决这个问题,发明了realloc函数;

void *realloc(void *s,unsigned int newsize);

在原先s指向的内存基础上重新申请内存,新的内存大小为new_size个字节;
如果原先内存后面有足够大的空间,就追加(下图情况1),如果后边的内存不够用(情况2),则relloc函数会在堆区找一个newsize个字节大小的内存申请,将原先内存中的内容拷贝过来,然后释放原先的内存,最后返回;
返回值:新内存的地址;
day24 动态内存申请_第1张图片
你看情况2 不够50个字节,所以realloc函数会在堆区申请一个连续的150个字节的空间,将原来的100个字节拷贝过来,然后将原来的内存释放调,然后返回新内存的地址;p返回150个字节的首地址;

内存泄漏

申请的内存,首地址丢了,找不了,再也没法使用了,也没法释放了,这块内存就被泄漏了;
例1:

char *p;
p = (char *)malloc(100);//接下来可以用p指向的内存了
p= "hello world";//p指向别的地方了 自此之后,再也找不到你申请的100个字节了,则动态申请的100个字节就泄漏了;

例2:

void fun()
{
   char *p;
   p =(char *)malloc(100);//接下来可以用p指向的内存了 没有free p, 谁申请,谁释放;fun里面的p是局部变量;
   
   ;
}
int main()
{
   fun();
   fun();//调用一次fun 泄漏100个字节;
   return 0;
}

解决方案1: 谁申请,谁释放

void fun()
{
   char *p;
   p =(char *)malloc(100);//接下来可以用p指向的内存了 没有free p, 谁申请,谁释放;fun里面的p是局部变量;
   
   ;
   free(p);
}
int main()
{
   fun();
   fun();//调用一次fun 泄漏100个字节;
   return 0;
}

解决方案2:还想在main使用这块内存, main函数释放

char* fun()
{
   char *p;
   p =(char *)malloc(100);//接下来可以用p指向的内存了
   
   ;
   return p;
}
int main()
{
   char *q;
   q = fun();
   //记得释放
   free(q);
   return 0;
}

你可能感兴趣的:(c语言,内存)