进击的小白——知识点:指针和malloc

先来理解几个概念:
  1. 指针的类型:指的是指针指向的变量(值)的类型,如定义一个指针变量int *p = NULL,指针p指向一个int型的变量,即指针的类型是int型。
  2. 指针指向的值的类型:与指针的类型相同,指针指向的值(变量)的类型就是指针的类型。
  3. 指针的值的类型:指针本身是一个地址值,这个地址值对应的内存储存着指针所指向的变量,而不管指针的类型(上面两个概念)是什么,指针变量本身的值(地址)的类型永远都是unsigned int型。
  4. 指针和指针变量:指针指的是地址,而指针变量指的是存放指针(地址)的变量。
int a = 0, *p;
p = &a;

p = &a;中,左边(p)是指针变量,右边(&a)是指针(地址)。

指针定义时分配的内存和用malloc分配的内存的区别:
  1. 定义指针时分配的内存是用来存放指针指向的变量的地址(指针变量本身的值)的,这个地址前面说过,是一个unsigned int型,只有几个字节(几个字节由系统决定)。
  2. 用malloc是申请出一段内存,用来存储数据,不是用来存储指针本身的,malloc返回开辟出的内存的首地址,存放在被赋值的指针中,使指针指向这块被开辟出来的内存。
什么时候指针需要用malloc分配内存,什么时候不需要

首先需要了解一下几点:

  1. C语言中,内存模型分为栈和堆,这两种模型内存的方式是不同的。
  2. 在栈中存放的变量是由系统自动管理的,在函数结束后系统会自动释放,不需要人为的任何操作。
  3. 在堆中存放的是用户自己管理的内存,手动分配的,malloc建立,系统不会在函数体执行结束后自动释放,需要用户手动通过free函数释放。
    因此,当需要对分配的空间进行自己的管理和释放时,需要实用malloc,或者分配的空间再函数结束后还需要存在。
    这样就有了“进击的小白——知识点:函数返回指针的应该指向什么变量”这篇博文中说的函数返回的指针应该指向什么变量,其中有一条就是“专门申请分配的空间(如用malloc)”,因为malloc申请的空间在函数执行完毕后不会自动释放。由于free后指针变量保存的地址没有改变,因此必须把指针变量的值变为NULL,否则会成为“悬空指针”。
free的作用

free执行的操作是:斩断指针变量和这块内存的对应关系。指针变量本身的值没有改变或消失,即指针变量本身保存的地址并没有改变,那块被释放的内存里面保存的值也没有改变,这是被释放的内存里保存的值被称为脏数据,可能维持原来的值,可能被清空,也可能被修改为其他的值。

关于内存泄漏

内存泄漏一般指的时堆内存,指程序从堆内存中分配出一块内存,但使用完后没有释放,导致这块内粗能不能再次使用。
首先了解一下C语言中内存分配情况,C语言中,根据数据在内存中存在的时间(生存周期)不同,讲内存空间分为三个区:

  1. 程序区:用于存储程序代码,即程序的二进制代码。
  2. 静态存储区:用于存储全局变量和静态变量,这些变量的空间在程序编译时就已经分配好了。
  3. 动态存储区:用于程序执行时分配的内存,又分为:堆区(heap)和栈区(stack)。堆区:用于动态内存分配,程序运行时由内存分配函数在对上分配内存,在C语言中,只能使用指针才能动态分配内存。栈区:在函数执行时,函数内存的局部变量和函数参数的存储单元的内存区域,函数运行结束时,这些内存区域会自动释放。
    在使用完开辟的内存后,及时使用free释放这段内存,可以有效的避免内存泄漏。
使用malloc需要注意的几点:
  1. malloc返回的首地址时void *型的,因此在有指针接收这个首地址时,需要进行强制类型转换,也就是说这块内存将来需要用来存储什么类型的数据。
  2. char *p = (char *)malloc(sizeof(char) * 100),这条语句的意思时在堆上分配了sizeof(char) * 100个字节的内存,返回这块内存的首地址,并把地址强制转换成char *型,赋值给char *型的指针变量p,同时告诉我们这块内存将用来存储char型的数据。这块内存只能通过指针变量p来访问,这块内存没有名字,对它的访问是匿名访问。
  3. 当申请的内存块大于堆中剩余的内存块时,会返回NULL,可以用if (p != NULL)来验证内存分配是否成功。
  4. free后,指针变量需要重新赋值成NULL,否则会成为“悬空指针”。
  5. 用malloc给指针分配一块内存,然后用memset对这块内存进行初始化,就可以像操作数组一样直接操作指针:
int *p = NULL;
p = malloc(sizeof(int) * 10);
memset(p, 0, sizeof(int) * 10);
p[0] = 1;
p[1] = 2;
......
  • 16
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值