C語言進階之內(nèi)存陷阱
看看這段代碼有什么問題?
char?*DoSomething(...)
{
char?i[32*1024];
memset(i,0,32*1024);
...
return?i;
}兩個重大的問題:
1. 臨時變量是通過堆棧實現(xiàn)的,太大的臨時變量數(shù)組會沖掉堆棧
2. 返回堆棧中的地址是非常危險的,因為堆棧中的值永遠是不確定的
看看這段代碼有什么問題?
void?DoSomething(...)
{
int?i;
int?j;
int?k;
memset(&k,0,3*sizeof(int));
}這段代碼的作用是將3個臨時變量清零
但是這段代碼有兩個假設:
1. 編譯器將i,j,k三個變量通過堆棧表示
2. 壓棧順序是i,j,k(假設堆棧是滿遞減堆棧)
3. 如果K在寄存器怎么辦?對k取地址操作將產(chǎn)生Data Aboart
關(guān)于臨時變量
不要對臨時變量作取地址操作,因為你不知道編譯器是否將這個變量映射到了寄存器不要反回臨時變量的地址,或臨時指針變量,因為堆棧中的內(nèi)容是不確定的(出了這個函數(shù),存放在堆棧中的局部變量就沒有意義了?。┎灰谏暾埓蟮呐R時變量數(shù)組,你的臨時變量是在堆棧中實現(xiàn)的,你有多大的堆棧呢?
現(xiàn)在要為一個矩形區(qū)或申請一塊內(nèi)存保存這塊的數(shù)據(jù),如果每個Pixle占用2個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沒有申請到,首先應該釋放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)于動態(tài)內(nèi)存
總是檢查動態(tài)內(nèi)存是否成功后再引用該指針!在分配struct空間是總是使用sizeof分配內(nèi)存時寧濫勿缺(別忘了加一)總是Free由malloc()函數(shù)返回的指針?按照ANSI C標準Free函數(shù)是沒有返回值的錯誤處理時不要忘了其它已經(jīng)分配空間的釋放





