2009-05-26 9 views
2

我認爲這是用sprintf的常用方法:C++如果使用sprintf打印更多字符,那麼會發生什麼情況,而不是字符指針已分配?

char pText[x]; 
sprintf(pText, "helloworld %d", Count); 

但到底發生了什麼,如果字符指針具有較少的內存分配,比它會被打印到?

即如果x小於sprintf的第二個參數的長度,該怎麼辦?

我在問,因爲我在sprintf語句後面的代碼中出現了一些奇怪的行爲。

+0

sprintf的這種用法很常見,但是非常錯誤:) – 2009-05-26 09:39:59

+0

它會在內存中寫下任何內容,這可能是堆棧或其他變量。 – pjc50 2010-01-13 12:38:48

回答

10

不可能一般地「回答」會發生什麼。這樣做會調用所謂的Undefined behavior,這基本上意味着可能發生任何事情。

這是一個好主意,乾脆避免這樣的情況下,並使用其中可用的安全功能:

char pText[12]; 
snprintf(pText, sizeof pText, "helloworld %d", count); 

注意如何snprintf()需要一個額外的參數爲緩衝區大小,比有不會寫更多房間。

0

你能拼寫Buffer Overflow嗎?一個可能的結果是堆棧損壞,並使您的應用程序容易受到基於堆棧的利用。

+2

這不是堆棧溢出,但緩衝區溢出 - -1 – 2009-05-26 09:28:45

+0

犯錯。你的意思是「緩衝區溢出」 – 2009-05-26 09:29:10

6

這是一個常見的錯誤,並導致char數組被覆蓋後的內存。所以,例如,char數組後面的內存中可能會有一些整數或其他數組,並且這些數組會被文本覆蓋。

查看關於整個問題(緩衝區溢出)的很好的詳細描述here。還有一些評論說,一些體系結構提供了一個snprintf例程,它具有第四個參數來定義最大長度(在你的情況x中)。如果你的編譯器不知道它,你也可以自己編寫它,以確保你不能得到這樣的錯誤(或者只是檢查你總是有足夠的空間分配)。

請注意,這樣的錯誤後的行爲是不確定的,可能會導致非常奇怪的錯誤。變量通常在可以被4整除的內存位置對齊,因此在大多數情況下,如果您已經寫了一個或兩個字節(即忘記爲NUL創建位置),您有時不會注意到該錯誤,但在其他位置出現奇怪的錯誤案例。這些錯誤很難調試,因爲其他變量會發生變化,錯誤通常會發生在完全不同的代碼部分。

2

在這種情況下的行爲是未定義的。通常情況下,你會崩潰,但你也可能看不到任何不良影響,奇怪的值出現在無關的變量和那種事情。您的代碼也可能會調用錯誤的函數,格式化硬盤驅動器並殺死其他正在運行的程序。最好通過爲你的緩衝區分配更多的內存來解決這個問題。

3

這被稱爲緩衝區溢出

sprintf將覆蓋恰好沿着pText地址的內存。由於pText在堆棧上,sprintf可以覆蓋局部變量,函數參數和返回地址,從而導致各種錯誤。這類代碼導致許多安全漏洞 - 例如攻擊者使用緩衝區溢出寫入指向自己代碼的新返回地址。

1

我已經做了這麼多次,你會收到內存損壞錯誤。據我所知,我記得我做了一些事情是這樣的: -

vector<char> vecMyObj(10); 
vecMyObj.resize(10); 
sprintf(&vecMyObj[0],"helloworld %d", count); 

但當向量的析構函數被調用時,我的程序收到內存損壞錯誤,如果大小爲少於10個,它會成功運行。

相關問題