C复习

就快毕业了,想想以后也没什么机会再来复习基础,那现在就拿些时间来好好复习复习基础。说实话,这么多年了,学了不少新东西,要做个什么东西,马上去学,然后就拿来用,但是对新知识的掌握也就是停留在看着教程会写实现自己功能的代码程序,而对这新知识其实根本就不怎么了解,更不要说掌握了,遇到问题,或者说跟新知识有关的专业术语啊,重点啊,难点啊,一概不懂。每次都说要好好复习复习基础,但是都没去做,到现在新学的东西掌握不透,以前学过的都忘得一干二净了。这次终于下定决心好好复习基础了。首先复习的是C语言,在复习中解决了很多之前没掌握和模棱两可的问题。malloc和realloc就是以前学C语言时没完全解决掉的问题,现在解决了。
malloc函数和realloc函数是动态分配内存的两个函数,它们是分配空间的,还有一个free是释放空间用的。这三个函数都是在内存的堆上进行的操作。
1 malloc函数
原型: extern void* malloc(unsigned int numb_bytes);
malloc分配空间,传入的参数是字节数,分配成功返回的是void* 指针,分配失败返回的是NULL。void*指针可以转化为其他类型的指针。所以在使用malloc的时候,每次都要对其进行强制类型转换。传入的参数呢,每次都要用sizeof先计算数据类型的字节数,然后再乘上想要分配的大小。而且可能会分配失败,所以每次使用malloc返回的时候都要判断一下指针是否为空。
 
例子:
type *p;
p=(type*)malloc(sizeof(type));
if(NULL == p)
{
    exit(OVERFLOW);
}
 
free(p);
p = NULL;
 
工作机制
malloc函数的实质体现在,它有一个将可用的内存块连接为一个长场的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个足以满足用户请求所需要的内存块。然后,将内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上检查各内存片段,对它们进行整理,将相连的小空闲块合并成较大的内存块,如果无法获得符合要求的内存块,malloc函数会返回NULL指针。
内存泄露的例子

#include <stdio.h>

#include<malloc.h>

#define MAX 100000000



int main()

{

int *a[MAX];

int i;

for(i = 0; i < MAX; i++)

{

a[i] = (int *)malloc(MAX);

}

return 0;

}

 

 

2 realloc函数

原型:extern void *realloc(void* mem_address, unsigned int newsize);

语法:指针名=(数据类型 *)realloc(要改变内存大小的指针,新的大小)。新的大小一定要大于原来的大小,不然会导致数据丢失。

功能:先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址.

返回值:如果重新分配成功则返回指向被分配内存的指针(返回的也是void*的指针,需要进行强制类型转化),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放.

例子:

int *p;

p = (int *)malloc(1000*sizeof(int));

p = (int*)realloc(p, (1000+500)*sizeof(int));

free(p);

p=NULL;

 

内存分配情况

如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address。

这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。那么就ok。得到的是一块连续的内存。

如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。(数据被移动了)。老块被放回堆上。

realloc()第二个参数的值如果是0,它的功能就相当于free

realloc()第一个参数的值如果是1,它的功能就相当于malloc

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted on 2013-05-05 01:05  WaterLoving  阅读(168)  评论(0)    收藏  举报