认识指针.docVIP

  • 0
  • 0
  • 约1.98千字
  • 约 6页
  • 2018-02-06 发布于河南
  • 举报
认识指针

重新认识指针 概述 通过最近软件上解决的BUG学习到一些新的东西,主要是内存越界,内存覆盖方面的问题,觉得有借鉴价值,故整理了这篇文档,供大家参考。 malloc() void *malloc(long NumBytes) 该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。 失败的原因NumBytes过大 NumBytes不合法,如NumBytes0等 内存碎片过多 free() void free(void *FirstByte) 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。失败的原因FirstByte指向的数据已经被释放,但是FirstByte不为NULL,FirstByte会被释放两次。 FirstByte值已经被重新赋值,变成了野指针,它指向的内存块永远得不到释放,这是造成内存泄露的主要原因。 FirstByte在运算过程当中没有归位,如FirstByte += 20, FirstByte -= 20;这种写法建议用临时指针替代。 FirstByte的结构被覆盖。(下面会讲到) . 函数使用 ??????? Void MyTest(void) { ??????? char *Ptr = NULL;?//必须要初始化 ??????? Ptr = (type*)malloc(100 * sizeof(type));?//分配的size需要乘以sizeof(type) ??????? if (NULL == Ptr)? ??? {? ??????? return;? ??? }? ??????? if (NULL != Ptr)? ??? {? ??????? free(Ptr);? ??????? Ptr = NULL;? ??? }? } 关于函数使用需要注意的一些地方: 申请了内存空间后,必须检查是否分配成功。 当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL。 这两个函数应该是配对使用。 释放的时候必要判断指针是否为NULL。 重新认识指针 什么是堆 堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表栈栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。… While(1) { Int I = 0; For(;1;) { Int j = 0; } … } 什么是静态存储区 全局区(静态区)(static)— 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。文字常量区常量字符串就是放在这里的,程序结束后由系统释放 。程序代码区存放函数体的二进制代码。…) 在0x003F6FD0之前有4byte的FD FD FD FD。 在0x003F6FD0 + 0x0A的地方,也就是这块内存结束的地方也有4byte的FD FD FD FD,这两个地方主要用于指针合法性的校验。 图中7777777777777才是你真正使用的内存。 备注:上面很多7777是我对内存初始化的值。 重新认识FREE() 现在先回到 案例分析,FREE的是否为什么会出错,OK,往下看。 正确FREE一个指针需要作以下几件事情: 根据指针的地址偏移4byte来校验开头位置的FDFDFDFD是否合法。 根据指针的地址偏移0x0A来校验结束位置的FDFDFDFD是否合法。 根据指针的地址偏移来校验内存块的长度,内存编号,有效标志位是否正确等。 我的理解是,FREE的本质只是置一个标志,告诉系统这段内存是否可用,真正的释放程序员不需要考虑 所以,申请完内存之后需要memset,因为别人之前用过的东西还在那放着,系统不一定帮你打扫干净了。 备注: 出现FREE失败或者程序在FREE的是否崩溃,直接根据上面提到的方法去检查指针的合法性。 结案 通过开始概要案例分析以及以上的两个函数的原理,得出以下结论与修改方向: 申请的内存已定已经被改写,导致FREE的是否校验不通过。 重现问题,察看MEMORY,果然起始位置中4个FD中的最后一个被改写。 察看代码,寻找+1,-1错误。 找到问题。换屏显示时,当步长和LED宽相等时,多了一个-1处理,导致内存越界,覆盖小了FD。 修改代码,问题解决。 结论 正文6

文档评论(0)

1亿VIP精品文档

相关文档