首先给出本次讨论话题的目录:
---------------------------------------------------------------------------------------------------------------
1.有关win32平台下调试堆的描述(上)
http://www.cnblogs.com/coolhysteria/archive/2012/09/22/Win32DebugCRTHeap1.html
2.有关win32平台下调试堆的描述(下)
http://www.cnblogs.com/coolhysteria/archive/2012/09/22/Win32DebugCRTHeap2.html
3.(转载)有关win32平台下调试堆的描述(实战篇)
http://www.cnblogs.com/coolhysteria/archive/2012/10/27/Win32DebugCRTHeapGoAndDo.html
----------------------------------------------------------------------------------------------------------------
心情莫名的好,索性就早早的起来了。这几天帮同学调试了些许程序,遇到了不少有关数组越界,堆指针引用错误等一系列问题,于是就准备写篇文章详细的描述一下如何发现,并避免这类难以发现且难以避免的问题。当然,在这里首先得感谢一位朋友,名字就不说了,因为他担心被人肉了(just a joke):P。
这篇文章的目的仅仅为了描述一个结构,有关调试堆(Win32 Debug CRT Heap )的结构(_CrtMemBlockHeader)。这个暂时放在一边,我们先聊聊别的话题。
1.什么是堆(heap),什么是栈(stack)?
在计算机中,一切运行中的数据都存放在内存中,以方便CPU取指令以及执行指令。
但是内存又划分为堆,栈,以及静态区。
栈:栈是由编译器维护(分配和释放)的一块比较小的内存区域(vc6.0下默认为1M,也可以在设置中更改:Project->Setting->Link中的output,其中reserve和commit字段),用于存放局部变量,以及函数栈帧(也就是说函数的压参,函数调用,使用参数,函数返回都是在栈中完成的),且栈的生长方向是从高地址向低地址增长。
堆:堆是由程序员维护(分配和释放)的一块比较大的内存区域(32bit系统下,理论可以达到4G),当然,程序结束的后,操作系统会介入进来释放掉掉分配的堆内存。一般在程序中看到malloc,realloc等库函数以及C++的new运算符都是在堆中分配内存,由这一点也可以看出,堆是靠这些库函数的一系列算法来实现的,所以分配堆得效率远远没栈高,同时也会导致我们在使用堆的时候容易出现很多问题。且堆的生长方向是从低地址向高地址增长。
2.堆和栈怎么使用,在哪看?
栈:
给出代码和示意图,用于详细直观描述栈
1 int main(int argc, char **argv) 2 { 3 int tmp = argc; 4 5 return 0; 6 }
OD中找到代码段的main函数调用(不要忘记了main函数也是函数 :P)如下:
函数调用,栈帧的情况如下:(od调试时候查看stack窗口)
堆:
给出代码和示意图,用于详细直观描述堆:
#include <stdlib.h> #include <string.h> int main(int argc, char **argv) { char *p = (char *)malloc(sizeof(char) * 10); strncpy(p, "hello,boy",10); free(p); p = NULL; return 0; }
malloc调用后,在内存中定位p,由p指向的那块区域便是我们分配在堆中的10bytes。(在vc++6.0中调试时候查看memory窗口)
3.什么是调试堆?有什么作用?
对于程序员来说,最蛋疼的时候便是遇到bug却找不到bug所在,找到bug却不知道如何修复bug。而比较低级的错误却刚好是难以避免的,比如数组越界,指针错误引用。在这一方面微软给大家提供了一个很方便的东西------调试堆。
首先回到刚刚第二段代码,在char *p = (char *)malloc(sizeof(char) * 10);执行后,我们理所当然的会认为操作系统给咱们分配了10个字节的大小,让我们再次看看这句话执行后,内存中到底有些什么东西。
再看看给堆内存中拷贝字符串后的情况:
以上两张图仔细比较之后,很容易发现,确实多分配了36个字节。先掉掉大家胃口,休息一会,关于这36个字节,将会在下一章节中(http://www.cnblogs.com/coolhysteria/archive/2012/09/22/Win32DebugCRTHeap2.html)详细描述。:D
大家也可以先自己研究一下,肯定能或多或少发现一些小细节 :D