烫与屯的问题

来源:互联网 发布:域名怎么申请域名邮箱 编辑:程序博客网 时间:2024/04/28 10:44

刚接触编程的同学一定遇到过这个问题:好不容易写出来的程序,一运行, 黑框框里面显示

烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫

或者

屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯

这是未初始化变量导致的。

当你编译处于Debug模式下的Visual Studio的程序时候,你会发现申请或销毁的内存具有奇怪的值,比如:0xCDCDCDCD或者0xDDDDDDDD,这是为在Win32平台下对内存的保护,防止泄露的措施。

运行时检查是VC编译器提供了运行时刻的对程序正确性/安全性的一种动态检查,可以在项目的C++选项中打开Small Type Check和Basic Runtime Checks来启用Runtime Check。 
同时,也可以使用/RTC开关来打开检查,/RTC后面跟c, u, s代表启用不同类型的检查。Smaller Type Check对应/RTCc, Basic Runtime Checks对应/RTCs和/RTCu。

 

code1:

#include "stdafx.h" #include <iostream> using namespace std;  const int MAX_LEN(11); int main(int argc, char* argv[]) {   //栈    char cTang[MAX_LEN];    cTang[MAX_LEN - 1] = 0;     //堆    char* pTun = new char[MAX_LEN];    pTun[MAX_LEN - 1] = 0;     cout << cTang << "\n";    cout << pTun << "\n";    //值    cout <<  static_cast<int>(cTang[0]) << "\n";    cout <<  static_cast<int>(pTun[0]) << "\n";      delete [] pTun;    pTun = NULL;    system("pause");    return 0; } 

代码运行的结果是:

烫烫烫烫烫 屯屯屯屯屯 -52 -51 请按任意键继续. . .

调试:

我们在打一个断点,Debug调试查看一下cTang和pTun的值。



可以看到Debug模式下

(1)我们的栈都用了0xcc填充,堆都用了0xcd填充,而不是空,也不是原来的本来内存。

(2)

栈空间未初始化的字符默认是-52,补码是0xCC,1个BYTE。两个就是0xCCCC. 0xCCCC在GBK编码中就是"烫"。

堆空间未初始化的字符默认是-51,补码是0xCD,两个-51在GBK编码中就是“屯”。

(3)

Release模式下,内存没有进行任何填充,原来是啥还是啥。

原来:

名字      描述 
0xCD   Clean Memory    申请的内存由malloc或者new完成 
0xDD   Dead Memory    释放后的内存,用来检测悬垂指针 
0xFD   Fence Memory    动态申请后的内存值,没有初始化。用来检测数组的下标界限 
0xAB   (Allocated Block?)    使用LocalAlloc()分配的内存 0x0DF0ADBA  Bad Food     使用LocalAlloc并且参数为LMEM_FIXED,但是还没写入 
0xCC    使用了/GZ选项,没有初始化的自动变量在DBGHEAP.C文件中,


有如下的定义: 
static unsigned char _bNoMansLandFill = 0xFD;   /* fill no-man's land with this */  
static unsigned char _bDeadLandFill   = 0xDD;   /* fill free objects with this */static unsigned char _bCleanLandFill  = 0xCD;   /* fill new objects with this */

Function    Description 
malloc    C/C++ 使用来申请内存空间,在C++中操作符new是在malloc的基础上被重载的_malloc_dbg   只有在Debug模式下才有效 
free    C/C++ 用来释放内存空间,在C++中操作符delete是在free的基础上被重载的_free_dbg   只有在Debug模式下才有效 
LocalAlloc  Win32 API,Windows内存管理器不会提供本地和全不堆LocalFree   Win32 API释放内存对象的句柄 
HeapAlloc   Win32 APIHeapFree   Win32 API

参考资料:

《程序员的自我修养》






0 0
原创粉丝点击