从C出发 30 --- 指针与堆空间

数组 就是变量的有序集,因此只有可以动态的创建一个变量,就可以动态的创建多个变量了,

堆空间就是一片内存区域,用于动态创建内存变量的区域

 

 

void 类型是基础类型,不是基础数据类型,为什么?因为没有办法 使用  void 类型创建一个变量,   

void  只能用来声明一个函数没有返回值,或者没有参数,除此之外没有别的用处了 ?

        错觉  ,  可以使用void 类型,来扩展成这样的指针类型    void*  

如果我们希望从一个指针从内存当中取数据,必须知道取多少字节的数据

假设  int* p   (每次读内存的时候,读4个字节的数据),将四个字节内存中的数据拿出来,当作一个整型使用

 

如果  p   是这样的类型     void* p ? 

可以保存起始地址,但是却没有办法读具体的数据了,因为 void 无长度信息,

void*  是一个合法的指针类型,但是却无法用  void*  类型的指针  来访问具体的内存数据,

因为   p   是 void*  类型的指针,意味着这种类型的指针,它可以保存任意类型的地址,因为这里的赋值语句都是正确的

 

printf("&f\n", *p)  这种写法错误,因为不可能使用 void* 类型的指针来访问内存中的数据,因为void 类型不具备长度信息,

char 代表的长度信息是 1 字节,int 4 字节, float 4 字节, double 8字节,所以这些基础的数据类型所扩展出来的指针,都能够访问数据出来,而void 不具备长度信息,没有办法使用void 扩展出来的指针去访问内存中的数据

编译器没有错误,意味着,这 4 条语句都是合法的

 使用  p  指针访问内存中的数据?

出现错误,表示 不能够使用 void* 类型的指针,去访问内存中的数据

如果非要访问内存中的数据怎么办?

 

 

赋值符号左右两边的类型不一样  不同的指针类型

编译结果告诉我们这里有问题, 所以,具体数据类型的指针之间,不能够相互的乱赋值,void*是一个特殊的类外


 void*   代表一个地址 ,这个地址就是我们所申请的内存的起始地址,

怎么归还,调用 free函数, 将之前申请到的内存的起始地址作为参数,调用 free 函数,就可以了

参数的这个  p  指针 所代表的地址,必须是堆空间中的地址,

如果非要用一个全局数据区里面的地址调用free,或者用一个栈空间区里面的地址调用free, 程序在后面的运行中会崩溃,free  所要释放的是堆空间

这里定义了一个指针  p , 这个指针 p 想要指向 int 类型的变量,具体指向哪个int 类型变量,p 是指向了堆空间里面的 4 个字节,换句话说,p 指向了int 类型的变量存在于 堆空间中,

*p = 100;    把 p 所指向的堆空间里面的 4 个字节 赋值为 100,将4 个字节的堆空间当成一个 int 来使用

 

 编译无误意味着这里的申请成功了,我们拿到了4 个字节的堆空间,并把这 4 个字节的堆空间当作int 类型的变量来使用

malloc -- -- -- -- 从堆空间里面申请内存,申请16 字节的内存,就是想申请 4 个int 类型的变量,换句话说这里想申请一个数组,这个数组存在于堆空间当中,这个数组里面有4 个int ,起始地址被 p 所指向,

 申请堆空间之后,如果不再使用了,必须归还

 

如果申请结果为 NULL (空),证明堆空间已经耗尽了

多次释放申请到的内存,会导致程序运行不稳定

 


malloc  申请到的东西只是这一片内存的起始地址,所以返回值是 void* 类型

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长生君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值