C语言-内存管理(浅析)

一、进程和进程空间:

1、什么是进程:

指程序加载到内存后开始执行,到执行结束这样一段时间概念。对同一个程序,每打开一次该程序都会拉起一个新进程,关闭一个则结束一个进程。(程序是静态概念,而进程是动态概念)

2、进程空间:

程序运行起来就成为一个进程,进程所占用的空间就是进程空间。我们来看一下,进程空间是什么样的。

3、栈(Stack):

栈中可存放任意类型的变量,但必须是 auto 修饰的局部变量。

        特点:随用随开,用完即消。内存的分配和销毁系统自动完成。

栈并不大,它的意义并不在于存储大数据,而在于数据交换。

        栈溢出:局部变量太多、太大,或者递归层数太多。

4、堆(Heap):

特点:堆可以存放任意类型的数据,但需要自己申请与释放。

堆的大小相对于栈来说很大,但实际使用中,受限于实际内存的大小和内存是否连续。


二、内存管理:

安全五步法:申请、判空、使用、释放、置空。

1、申请:malloc()   

2、扩容(缩容):realloc() 

      扩容会出现两种情况:

      1)原内存后面空间足够,则直接在原内存后面开辟空间扩容;

      2)原内存后面空间不足,此时会找一块新的大空间,并将原内存内容拷贝过来,然后扩容达到目的。

缩容后,原空间被缩小部分的内存中的内容将不可用。

3、释放:free()

使用示例如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	char *p = (char *)malloc(10 * sizeof(char));  //申请
	if (p == NULL)				      //判空                           
	{
		printf("error");
		exit(-1);
	}
	strcpy(p, "china");		 //使用                      
	printf("start : %s\n", p);
	p = (char *)realloc(p, 20 * sizeof(char));    //扩容
	if (p == NULL)			 //再次判空
	{
		printf("error");
		exit(-1);
	}
	strcpy(p, "hello china");       //12个字节               
	printf("after : %s\n", p);
	free(p);	                //释放
	p = NULL;	                //置空								  

	getchar();
	return 0;
}

4、应用----以动态数组为例:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	int len;
	printf("start len :");
	scanf("%d", &len);
	int oldLen = len;
	int *p= (int *)malloc(len * sizeof(int));	//原空间
	if (p == NULL)
	{
		printf("error");
		exit(-1);
	}
	//memset(p, 0, len * sizeof(int));每个字节初始化为零
	for (int i = 0; i < len; i++)
	{
		p[i] = 100 + i;
		printf("%d\n",p[i]);
	}
	printf("after len : ");
	scanf("%d", &len);
	p = (int *)realloc(p,len * sizeof(int));	//扩大(缩小)
	if (p == NULL)
	{
		printf("error");
		exit(-1);
	}
	for (int i = 0; i < len; i++)
	{
		if (i>=oldLen)
		{
			p[i] = 200 + i;
		}
		printf("%d\n", p[i]);
	}
	free(p);
	p = NULL;
	system("pause");
	return 0;
}

三、总结:

C语言内存管理,是一个重要话题,值得深入探讨。防止内存泄漏,至关重要。

常见错误:

1、malloc和free不配对:导致多次申请或多次释放出错。

2、忽略置空与判空:释放以后指针未置为 NULL再次作判空使用或释放以后继续非法使用。

......
char*p=(char*)malloc(100);
strcpy(p,"hello");
free(p);       // 此时p所指的内存被释放,但是p所指的地址仍然不变
//p = NULL;忘了此句,后而又用到了p
......
if(NULL!=p)    //没有起到防错作用
{
    strcpy(p,"hello"); //出错
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值