C语言内存管理与指针

深入解析野指针问题,内存管理问题及大小端问题

野指针问题

什么是野指针
野指针就是指向未知位置的指针
野指针产生原因
野指针产生的原因主要有两个:
1.定义指针时未对指针进行初始化操作。
2.在用free()函数释放内存空间时没有将指针指向NULL。
第一个原因很好理解,这里解释一下第二个产生原因。C语言中通常情况下使用malloc()函数来申请内存空间,malloc()函数的用法如下:
void * malloc(long NumBytes )
该函数分配了NumBytes个字节,并返回指向这块内存的指针,该指针的类型为void,如果分配失败则返回的指针为NULL,分配成功则指针指向堆中的一块内存,至于这块内存是怎么来的,我们再来深究一下。操作系统中有一个记录空闲内存地址的链表,当操作系统收到程序的申请时,就会遍历该链表,寻找空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。程序用完这段内存后要释放,否则就会造成内存泄漏,释放时使用free()函数,该函数的用法如下:
void free(void * FirstByte )
注意这个函数释放的是内存空间,并没有释放指针,也就是说指针依旧指向这段内存,只不过这段内存中的内容已经没有意义了,所以需要将指针设为NULL,否则该指针就变为了野指针。释放内存空间意味着将堆结点重新放回空闲结点链表。
野指针的危害
1.指向不可访问的地址,譬如内核空间:触发段错误
2.指向一个可访问的、没什么意义的地址,譬如空闲栈空间:不会触发明显错误,但会留下安全隐患
3.指向一个访问的被程序使用的地址,譬如说一个变量:导致数据被损害或者程序崩溃,危害最大
这里我们引申一下段的相关知识:
C/C++程序经过编译连接后形成二进制映像文件,这些文件包含:堆,栈,数据段和代码段。栈用来存放函数的参数值,局部变量等值,堆一般由程序员分配释放,程序代码区用来存放函数体的二进制代码,数据段由三部分组成:(1)只读数据段:用来存放不会更改的数据如const修饰的变量及程序中使用的文字常量。(2)已初始化的读写数据段:存放已经初始化的全局变量和已经初始化的静态局部变量。(3)未初始化段(BSS):用来存放程序中未初始化的全局变量和静态变量。

栈和堆

程序的内存分配
1.栈区
由编译器自动分配释放,存放函数的参数值,局部变量的值等
2.堆区
由程序员分配释放,若程序员不释放,有可能被操作系统回收
3.全局区(静态区)
全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放
4.文字常量区
常量字符串就是放在这里的程序结束后由系统释放
5.程序代码区
存放函数体的二进制代码

堆是一种内存管理方式,用于动态分配和释放程序所申请的内存空间,由程序员分配释放,若程序员不释放,有可能被操纵系统回收。堆的生命周期从malloc申请内存时开始,到free释放内存时结束。通常在以下操作中调用堆:
1.需要的内存很大
2.需要的内存容量不确定

由编译器自动分配释放,存放函数的参数值,局部变量等值。其操作方式类似于数据结构中的栈。栈是属于线程的,每一个线程都会有一个自己的栈。栈又分为好几个区域,他们叫做栈帧,一个栈帧就是一个函数,需要调用该函数的时候局部变量就入栈,函数return的时候就会弹出栈,所以他们的生命周期是从函数的开始到函数结束。

大小端问题

计算机存储系统的大小端,大端模式:一个变量的高字节存储在低地址,小端模式:一个变量的低字节存储在低地址。
大端模式:
在这里插入图片描述

小端模式:
![小端模式](https://img-blog.csdnimg.cn/49a243feb01f426ab720ce208fa9b2d3.png
通信系统中的大小端问题,先传高字节的为大端模式,先传低字节的为小端模式。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值