动态存储分配

 

静态存储方式:是指在程序运行期间由系统分配固定的存储空间的方式。

动态存储分配:是指在程序运行期间根据需要进行动态的分配存储空间的方式。

 

使用函数:malloc()、free()      需要malloc.h头文件的支持

函数声明:void *malloc(unsigned int  字节数)       

该函数的返回值类型是:void * 称为无类型指针 (因为不确定未来给什么类型用)。

              返回值返回的是申请好的空间的首地址

对于用malloc()函数申请的空间,必须使用free()函数进行释放!

 

colloc()函数:

函数声明:void *calloc(unsigned n,  unsigned  size);

在内存的动态存储区中分配n个长度为size的连续空间。

用calloc函数可以为一维数组开辟动态存储空间,n为数组元素个数,每个元素长度为size。    

 

(1)

int  *p;

double *q;

错误形式:p = malloc(1000); // 向操作系统申请1000个字节的内存空间。

                 q = malloc(1000);

正确形式:p = (int *)malloc(1000);

                  q = (double *)malloc(1000);

free(p);         //释放的是p所指向的空间

free(q);    //为什么只告诉首地址,不告诉长度呢?  

               //因为在申请空间时就把首地址和长度写到了已分配空间表,所以告知了首地址后,会自动查找出长度

 

上述两次空间申请得到了怎样的东西?

*(p + 1)  <=>  p[1]               p[0] … p[249] 其实可以看成是申请了一个拥有250个int元素的数组p!

*(q + 1)  <=>   q[1]              q[0] … q[124] 其实可以看成是申请了一个拥有125个double元素的数组q!

 

(2)  这种方式比较常见,而且修改数值时比较方便

int n;

int *p;

scanf(“%d”, &n);

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

 

(3)

int *p;

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

其实,这相当于申请了一个整型变量空间!以后,可以通过*p实现对这段空间的引用(赋值、运算……)。

 

(4)对于malloc()和free(),在使用时要万分小心!

int i;

int *p;

 

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

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

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

free(p);

 

动态存储分配_第1张图片

程序循环,在第二次循环时,用新申请的空间的首地址值,覆盖了p空间原来的第一块空间的首地址值,使得第二块空间不能再被引用,甚至不能释放第一块和第二块空间!这就是著名的“内存泄露”问题!非常严重!!!

 

对于for(i = 0; i < 3; i++)  free(p);是将“以p的值为首地址的空间“释放3次!

其实,根本就轮不到第三次释放,在第二次释放时,系统就崩溃了。  

free(p)释放的是以p的值为首地址所指向的空间,p空间本身是不会被释放的。因为p指向第三块空间,所以将释放第三块空间,

内存的回收与释放是根据已使用空间表,给定首地址,它找到表格里想对应的那一行,把那一行转到可用空间,进行内存合并。第二次free,它将在已分配空间表里找之前的地址,但是已经没了,所以系统就崩溃了。

 

(5)

int *fun1(){
    int a[10];
    return a;
}
int *fun2(){
    int *p;
    p = (int *)malloc(sizeof(int) * 10);
    return p;
}
void main(void){
    int *q;
    int *p;
    p = fun1();
    *p = …;
    q = fun2();
    *q = …;
    free(p);
    free(q);
}
上述程序段存在的问题:
1、fun1()函数中的int a[10],是这个函数的局部(私有、临时)数组空间,将随着fun1()函数的运行结束而释放!fun()函数将这个已经释放的空间的首地址传递给主调函数,并在主调函数中对其空间进行操作,这就是错误的!(逻辑错误,即,不能被C便以软件发现的错误!)
2、int a[10]是fun1()函数的局部数组,将被fun1()函数的”}”释放空间;再一次在main()函数中释放该空间,将引起系统崩溃!
上述程序段也说明一种malloc()动态存储分配在使用时的一种模式:可以在两个不同的函数中,一个申请,一个释放!

 

你可能感兴趣的:(C语言,数据结构与算法)