首先来解释malloc(0)的问题,这个语法是对的,而且确实也分配了内存,但是内存空间是0,就是说返回给你的指针是不能用的,感觉奇怪吧?但是从操作系统的原理来解释就不奇怪了,这要涉及操作系统维护内存的方法来说了,在内存管理中,内存被分为2部分,栈和堆,栈有自己的机器指令,是一个先进后出的数据结构,我就在这里不再过多解释了,malloc分配的内存是堆内存,由于堆没有自己的机器指令,所以要有系统自己编写算法来管理这片内存,通常的做法是用链表,在每片被分配的内存前加个表头,里面存储了被分配内存的起始地址和大小,你的malloc返回的就是表头里的起始指针,这个地址是由一系列的算法得来了,通常不会为0,一旦分配成功,就返回一个有效的指针,对于分配0空间来说,算法已经算出可用内存的起始地址,但是你占用0空间,所以对那个指针操作就是错误的,操作系统一般不知道其终止地址,因为有占用大小就可以推出终止地址,还有就是即使分配0空间也要释放它,其实是释放的链表结点还有,返回的指针是可用地址的起始地址,虽然你可以无限赋值,但是其实是错误的,因为可能有其他有用的数据在那一片区域,如果指针越界就会出现意想不到的事情,不懂的再问 |
C规定,未初始化变量的初值为0,这个清0的操作是由启动代码完成的,还有已初始化变量的初值的设置,也是由启动代码完成的。为了启动代码的简单化,编译链接器会把已初始化的变量放在同一个段:.data,这个段的映像(包含了各个变量的初值)保存在“只读数据段”,这样启动代码就可以简单地复制这个映像到 .data 段,所有的已初始化变量就都初始化了。而未初始化变量也放在同一个段:.bss,启动代码简单地调用 memset 就可以把所有未初始化变量都清0。头疼的野指针
初始野指针(1)野指针通常是因为指针变量中保存的值不是一个合法的内存地址而造成的(2)野指针不是NULL指针,是指向不可用内存的指针(3)NULL指针不容易用错,因为NULL语句和好判断一个指针是不是NULLC语言没有任何手段可以判断一个指针是否是野指针野指针的由来(1)局部指针变量没有被初始化(2)使用已经释放过后的指针
(3)指针所指向的变量在指针之前被销毁
经典错误,你犯了吗?非法内存操作分析(1)结构体成员指针未初始化(2)没有为结构体指针分配足够的内存
d1中的p是野指针,p没有分配动态内存空间,p指向的是随机的d2中的p是分配呢5个int,但是分配10个,这种bug很难查内存初始化分析(1)内存分配成功,但未被初始化
内存越界分析(1)数组越界
内存泄漏分析
设计程序最好要单入口单出口多次释放指针
谁申请谁释放使用已经释放的指针
交通规则,还是应该遵守C语言中的交通规则(1)用malloc申请了内存之后,应该立即检查指针值是否为NULL,防止使用值为NULL的指针
(2)牢记数组长度,防止数组越界操作,考虑使用柔性数组
(3)动态申请操作必须和释放操作匹配,防止内存泄漏和多次释放
(4)free指针之后必须立即赋值为NULL
新闻热点
疑难解答