C语言之内存分区与动态数组

 

一.内存的动态分配

内存区包括:栈区、堆区、全局区或静态区、代码区;

栈区(stack)是由编译器自动分配释放,存放函数调用、参数值、局部变量的值等;

//栈区分析
#include<stdio.h>
char* getstr()
{
    //函数结束后栈区内存释放
	char str[] = "abcdef";
	printf("str = %s\n",str);
	return str;
}
int main()
{
	char buf[128] = {0};
    //strcpy(buf, getstr())
    //printf("buf = %s\n", buf);
	
	char *p;
	p=getstr();
	printf("p = %s\n", p);        //乱码,不确定
	
	return 0;
}

堆区(heap)是一般由程序员分配释放,C语言允许建立内存动态分配区域,以存放一些临时数据的自由存储区;

//堆区分析
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* getstr()
{
	char *str = (char *)malloc(100);
	if(str == NULL)
		return NULL;
	strcpy(str,"abcdef");
	return str;
}
int main()
{
	char buf[128] = {0};
    //strcpy(buf, getstr())
	//printf("buf = %s\n", buf);
	
	char *p = NULL, *q;
	p=getstr();
	if(p != NULL)
	{
		q=p;
		printf("p = %s\n", p);
		//p指针释放前后指向没有变化
		printf("p = %d\n", p);
		free(p);
		printf("p = %d\n", p);
	}
	p = NULL;	
	return 0;
}

全局区静态区(static)是全局变量和静态变量的存储区,初始化和未初始化分开放置;字符串常量和其他常量的存储位置,程序结束后由操作系统释放;

//全局变量区分析,相同字符串常量地址相同
#include<stdio.h>
char* getstr1()
{
	char* p = "abcdef";
	return p;
}
char* getstr2()
{
	char* q = "abcdef";
	return q;
}
int main()
{
	char* p=NULL;
	char* q=NULL;
	
	p=getstr1();
	q=getstr2();
	//p,q地址相同
	printf("p = %s, p = %d\n",p,p);
	printf("q = %s, q = %d\n",q,q);

}

代码区:存储函数体的二进制代码。

内存的动态分配是通过系提供的库函数实现的,主要有malloccallocfreerealloc这4个函数。

malloc函数原型为 void *malloc(unsigned int size);其作用是在内存的动态储存区中分配一个长度为size的连续空间。形参size的类型定为无符号整型(不允许是负数)。此函数的值是分配区域的第一个字节的地址。如果此函数未能程成功的执行则返回空指针NULL。

calloc函数原型为 void *calloc(unsigned n,unsigned size); 其作用是在内存的动态储存区中分配n个长度为size的连续空间,足以保存数组。函数返回指向所分配区域的起始位置的指针,如果分配不成功,返回NULL。

free函数原型为 void free(void *p);其作用是释放变量p所指向的动态空间。

  • free只是释放了malloc所申请的内存,并没有改变指针的值;
  • 由于指针所指向的内存空间已经被释放,所以其他代码有机会改写其中的内容,相当于该指针从此指向了自己无法控制的区域;
  • 为了避免错误,所以最好在free之后,使指针指向NULL;

根据原理的解释分析:free函数的作用只是告诉操作系统该内存不用了,可以收回,操作系统就把该内存链接到链接表上,

但是这段内存用户还是可以访问到的,只是该内存的值可能已经发生了变化。
 

realloc函数原型为 void *realloc(void *p,unsigned int size);将已经通过malloc函数或calloc函数获得的动态空间重新分配

以上函数声明需要#include<stdlib.h>头文件声明。

二.动态数组实现

一维动态数组实现

    //一次性分配数组
    int *array,N;                            //定义指针及数组个数
    array = (int *)malloc(sizeof(int)*N)       //动态分配一维数组
    //未知数组个数,多次分配数组
    str = (char*)malloc(sizeof(char));         
    str = (char*)realloc(str, sizeof(char)*n);  //重新分配
    
    //释放内存,指针指向并没有变
    free(str);
    str = NULL;

二维动态数组实现

    //calloc实现  
    int M,N	                               
    array=(int **)calloc(M,sizeof(int*));       
    for(i=0;i<M;i++)
	    array[i]=(int *)calloc(N,sizeof(int));
    //malloc实现
    int M,N	                               
    array=(int **)malloc(sizeof(int *)*M);       
    for(i=0;i<M;i++)
	    array[i]=(int *)malloc(sizeof(int)*N);

    //释放内存
    for(i = 0; i < n; i++)
    {
        if(array[i])
        {
            free(array[i]);
            array[i] = NULL;
        }    
    }
    if(array)
    {
        free(array[i]);
        array = NULL;
    }

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值