转自:https://blog.csdn.net/csw_100/article/details/5665393
在VC6下调试程序,可能会遇到诸如指令引用“0xcccccccc”,该内存不能为Read的报错
究其原因,就debug版中的堆栈中的局部变量(包括指针)在明确初始化之前都用0x0cc进行初始化,因此,未初始化时 候的指针是指向地址0x0cccccccc的,而这段地址一来是处于内核地址空间,一般的应用程序是无权访问的,上面的报错就是这样产生的。因此,一旦遇 到上述报错,基本可以认定程序中出现了野指针。
另外一方面cc对应着int 3调试中断,堆栈中的存放的局部数据一般情况下是只读的,当发生意外执行堆栈里面的数据就会引发该调试中断。
可以认为0x0cc就是有特殊含义的占位符,对于指针而言,它跟NULL是一个意思,其它具有特殊意义的占位符还有:
0xcdcdcdcd - Created but not initialized
0xdddddddd - Deleted
0xfeeefeee - Freed memory set by NT's heap manager
0xcccccccc - Uninitialized locals in VC6 when you compile w/ /GZ
0xabababab - Memory following a block allocated by LocalAlloc()
例如:
char *str= "abc";
char *str1 ;
char *str2=strcpy(str1,str);
就会弹出0xc0000005 access violation的错误提示,因为strcpy的内部会将str拷贝到str1所在的地址空间,而未初始化的str初始化为0xcccccccc,这段地址处于内核地址空间,无权访问,因此报错
引申出来的问题:
char *str= "abc";
char *str1 ="sdfsd";
char *str2=strcpy(str1,str);
也会弹出0xc0000005 access violation,这又是为什么呢
这就涉及到了常量存储区的问题
在C++ 中, 内存分成5 个区,他们分别是堆、栈、自由存储区、全局/ 静 态存储区和常量存储区。
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参 数等。
堆,就是那些由new 分配的内存块,他们的释放编译器不去 管,由我们的应用程序去控制,一般一个new 就要对应一个delete 。 如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
自由存储区,就是那些由malloc 等 分配的内存块,他和堆是十分相似的,不过它是用free 来结束自己的生命的。
全局/ 静 态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C 语言中,全局变量又分为初始化的和 未初始化的,在C++ 里面没有这个区分了,他们共同占用同一块内存区。
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量, 不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)
正如黑线标记的说法 "sdfsd"以常量形式存于常量存储区,这一段的内存也是不可更改的,因此当然弹出错误了