C語言進(jìn)階之內(nèi)存陷阱
看看這段代碼有什么問題?
char?*DoSomething(...) { char?i[32*1024]; memset(i,0,32*1024); ... return?i; }
兩個(gè)重大的問題:
1. 臨時(shí)變量是通過堆棧實(shí)現(xiàn)的,太大的臨時(shí)變量數(shù)組會(huì)沖掉堆棧
2. 返回堆棧中的地址是非常危險(xiǎn)的,因?yàn)槎褩V械闹涤肋h(yuǎn)是不確定的
看看這段代碼有什么問題?
void?DoSomething(...) { int?i; int?j; int?k; memset(&k,0,3*sizeof(int)); }
這段代碼的作用是將3個(gè)臨時(shí)變量清零
但是這段代碼有兩個(gè)假設(shè):
1. 編譯器將i,j,k三個(gè)變量通過堆棧表示
2. 壓棧順序是i,j,k(假設(shè)堆棧是滿遞減堆棧)
3. 如果K在寄存器怎么辦?對(duì)k取地址操作將產(chǎn)生Data Aboart
關(guān)于臨時(shí)變量
不要對(duì)臨時(shí)變量作取地址操作,因?yàn)槟悴恢谰幾g器是否將這個(gè)變量映射到了寄存器不要反回臨時(shí)變量的地址,或臨時(shí)指針變量,因?yàn)槎褩V械膬?nèi)容是不確定的(出了這個(gè)函數(shù),存放在堆棧中的局部變量就沒有意義了?。┎灰谏暾?qǐng)大的臨時(shí)變量數(shù)組,你的臨時(shí)變量是在堆棧中實(shí)現(xiàn)的,你有多大的堆棧呢?
現(xiàn)在要為一個(gè)矩形區(qū)或申請(qǐng)一塊內(nèi)存保存這塊的數(shù)據(jù),如果每個(gè)Pixle占用2個(gè)bit,如何分配內(nèi)存?
char?*buffer buffer?=?malloc(x*y/4);×
buffer = malloc(x*y/4+1);
看看這段代碼有什么問題?
char?*DoSomething(...) { char?*p,*q; if((p?=?malloc(1024))?==?NULL)? return?NULL; if((q?=?malloc(2048))?==?NULL) return?NULL; ... return?p; }
如果q沒有申請(qǐng)到,首先應(yīng)該釋放p,然后再返回NULL!
看看這段代碼有什么問題?
void?FreeWindoTree(windows?*Root) { if(Root?!=?NULL) { windows?*pwnd; /*釋放pwndRoot的子窗口...*/ for(pwnd?=?Root->child;pwnd?!=?NULL;?pwnd?=?pwnd->Sibling) FreeWindoTree(pwnd); if(Root->strWndTitle?!=?NULL) FreeMemory(Root->strWndTitle); FreeMemory(Root); } }
pwnd已經(jīng)被釋放了,但是在for循環(huán)中被再次引用
關(guān)于動(dòng)態(tài)內(nèi)存
總是檢查動(dòng)態(tài)內(nèi)存是否成功后再引用該指針!在分配struct空間是總是使用sizeof分配內(nèi)存時(shí)寧濫勿缺(別忘了加一)總是Free由malloc()函數(shù)返回的指針?按照ANSI C標(biāo)準(zhǔn)Free函數(shù)是沒有返回值的錯(cuò)誤處理時(shí)不要忘了其它已經(jīng)分配空間的釋放