你很烫吗?我很烫——关于栈区和静态存储区的思考
1.引言
相信經(jīng)常用VC的朋友對(duì)屏幕輸出的一大堆“燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙”不會(huì)陌生,但是也許會(huì)很奇怪,為什么會(huì)出現(xiàn)“燙”字呢?莫非改程序?qū)е孪到y(tǒng)運(yùn)行緩慢,發(fā)熱過高???非也!下面解釋一下,有錯(cuò)誤的地方請(qǐng)指正:
如果逆向Debug模式下一個(gè)C程序,發(fā)現(xiàn)棧區(qū)開辟的存儲(chǔ)空間都是使用0CCCCCCCCh來填充4字節(jié)單位的,也就是說,棧區(qū)開辟的存取局部變量的空間的每一個(gè)字節(jié)都被0xCC填充了。(為什么用0xCC,這個(gè)是int 3h的機(jī)器碼,下斷點(diǎn)用的)兩個(gè)0xCC合起來輸出時(shí)恰好對(duì)應(yīng)中文“燙”字。
這也就不奇怪程序輸出那么多“燙”了。
2.實(shí)例演示
實(shí)例一:#include "stdafx.h" #include <string.h>int _tmain(int argc, _TCHAR* argv[]) {char s[256] = {0}; // 定義一個(gè)數(shù)組memset(s, 0xCC, sizeof(s)); // 用0xCC填充printf("%s\n", s); // 輸出return 1; }
查看運(yùn)行結(jié)果:
程序輸出結(jié)果
實(shí)例二:
#include "stdafx.h" #include <string.h>int _tmain(int argc, _TCHAR* argv[]) {char s[256]; // 系統(tǒng)默認(rèn)用0xCC填充printf("%s\n", s); // 輸出return 1; } 程序輸出還是”很燙“。
實(shí)例三:把字符數(shù)組定義為全局變量
#include "stdafx.h" #include <string.h>char s[256]; // 全局變量int _tmain(int argc, _TCHAR* argv[]) {printf("%s\n", s); // 輸出return 1; }
這次系統(tǒng)輸出了空,沒有燙了!為什么???
其實(shí),全局變量分配在”全局/靜態(tài)存儲(chǔ)區(qū)“中,局部變量分配在棧中,我們可以定義一個(gè)很大的數(shù)組,如果是局部的,會(huì)導(dǎo)致程序棧溢出,因?yàn)闂5目臻g大小是有限制的;而全局的則不會(huì)。
另外需要注意,這些”燙燙燙燙燙燙燙“現(xiàn)象只會(huì)在Debug模式中出現(xiàn),在Release模式中不會(huì)出現(xiàn)。
如果你對(duì)”燙燙燙燙燙燙燙“表示很熟悉,那么”屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯“你見過嗎?應(yīng)該吧。我本人以前經(jīng)常遇到”燙“,但很少遇到后者。
實(shí)例四:動(dòng)態(tài)分配內(nèi)存空間
#include "stdafx.h" #include <stdio.h> #include <stdlib.h>int main(int argc, char* argv[]) {char *s = (char *)malloc(sizeof(char) * 256);puts(s);free(s);return 0; }
運(yùn)行程序,頓時(shí)滿屏的”屯“字出現(xiàn)在眼前,有圖有真相:
程序輸出結(jié)果
因?yàn)?#xff0c;動(dòng)態(tài)分配的空間開辟于堆,VC的Debug用0xCD填充堆的空間,兩個(gè)0xCD和在一起就是屯了。 與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的你很烫吗?我很烫——关于栈区和静态存储区的思考的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。