C语言深度解剖笔记6之内存管理;

54 篇文章 0 订阅

什么是野指针

野孩子:没人要,没人管的孩子;行为动作不守规矩,调皮捣蛋的孩子。所以野指针就是指向不明,指向地址随机的指针。

定义指针变量的同时最好初始化为NULL,用完指针之后也将指针变量的值设置为NULL。也就是说除了在使用时,别的时间都把指针“栓”到0 地址处。这样它就老实了。

栈、堆和静

我们可以简单的理解为内存分为三个部分:静态区,栈,堆。堆栈就是栈,

静态区:保存自动全局变量和static 变量(包括static 全局和局部变量)。静态区的内容
在总个程序的生命周期内都存在,由编译器在编译的时候分配。

栈:保存局部变量。栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁。其特点是效率高,但空间大小有限。

堆:由malloc 系列函数或new 操作符分配的内存。其生命周期由free 或delete 决定。
在没有释放之前一直存在,直到程序结束。其特点是使用灵活,空间比较大,但容易出错。

常见的内存错误及对策

1>指针没有指向一块合法的内存,定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内存

结构体成员指针未初始化:当结构体内的指针成员变量未初始化的时候,指针并没有指向一个合法的地址,看个例子:

struct student
{
char *name;
int score;
}stu,*pstu;
intmain()
{
strcpy(stu.name,"Jimy");
stu.score = 99;
return 0;
}

结构体内部char *name 这成员在定义结构体变量stu 时,只是给name 这个指针变量本身分配了4 个字节。name 指针并没有指向一个合法的地址,这时候其内部存的只是一些乱码。所以在调用strcpy 函数时,会将字符串"Jimy"往乱码所指的内存上拷贝,而这块内存name 指针根本就无权访问,导致出错。解决的办法是为name 指针malloc 一块空间。注意是给这个name指针malloc一块空间。

2>不管什么时候,我们使用指针之前一定要确保指针是有效的

一般在函数入口处使用assert(NULL != p)对参数进行校验。在非参数的地方使用if(NULL != p)来校验。但这都有一个要求,即p 在定义的同时被初始化为NULL 了。比如上面的例子,即使用if(NULL != p)校验也起不了作用,因为name 指针并没有被初始化为NULL,其内部是一个非NULL 的乱码。

关于malloc的函数:

malloc 函数的原型:(void *)malloc(int size).

malloc 函数的返回值是一个void 类型的指针,参数为int 类型数据,即申请分配的内存
大小,单位是byte。内存分配成功之后,malloc 函数返回这块内存的首地址。你需要一个指
针来接收这个地址但是由于函数的返回值是void *类型的,所以必须强制转换成你所接收
的类型。也就是说,这块内存将要用来存储什么类型的数据。
比如:
char *p = (char *)malloc(100);
在堆上分配了100 个字节内存,返回这块内存的首地址,把地址强制转换成char *类型后赋
给char *类型的指针变量p。

但是,每次你都能分配成功吗?不一定,如果所申请的内存块大于目前堆上剩余内存块(整块),则内存分配会失败,函数返回NULL。注意这里说的“堆上剩余内存块”不是所有剩余内存块之和,因为malloc 函数申请的是连续的一块内存。

既然malloc 函数申请内存有不成功的可能,那我们在使用指向这块内存的指针时,必须用if(NULL != p)语句来验证内存确实分配成功了,与malloc 对应的就是free 函数了,。free 函数就是把这块内存和p 之间的所有关系斩断。从此p 和那块内存之间再无瓜葛。至于指针变量p 本身保存的地址并没有改变,但是它对这个地址处的那块内存却已经没有所有权了。

使用free 函数之后指针变量p 本身保存的地址并没有改变,那我们就需要重新把p的值变为NULL:p = NULL

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值