如何解決C 中溢位的問題,如何解決棧溢位

2022-07-07 09:10:14 字數 4196 閱讀 8094

1樓:常武工業設計

一、為什麼會出現記憶體溢位問題?

導致記憶體溢位問題的原因有很多,比如:

(1) 使用非型別安全(non-type-safe)的語言如 c/c++ 等。

(2) 以不可靠的方式存取或者複製記憶體緩衝區。

(3) 編譯器設定的記憶體緩衝區太靠近關鍵資料結構。

下面來分析這些因素:

1. 記憶體溢位問題是 c 語言或者 c++ 語言所固有的缺陷,它們既不檢查陣列邊界,又不檢查型別可靠性(type-safety)。眾所周知,用 c/c++ 語言開發的程式由於目標**非常接近機器核心,因而能夠直接訪問記憶體和暫存器,這種特性大大提升了 c/c++ 語言**的效能。

只要合理編碼,c/c++ 應用程式在執行效率上必然優於其它高階語言。然而,c/c++ 語言導致記憶體溢位問題的可能性也要大許多。其他語言也存在內容溢位問題,但它往往不是程式設計師的失誤,而是應用程式的執行時環境出錯所致。

2. 當應用程式讀取使用者(也可能是惡意攻擊者)資料,試圖複製到應用程式開闢的記憶體緩衝區中,卻無法保證緩衝區的空間足夠時(換言之,假設**申請了 n 位元組大小的記憶體緩衝區,隨後又向其中複製超過 n 位元組的資料)。記憶體緩衝區就可能會溢位。

想一想,如果你向 12 盎司的玻璃杯中倒入 16 盎司水,那麼多出來的 4 盎司水怎麼辦?當然會滿到玻璃杯外面了!

3. 最重要的是,c/c++ 編譯器開闢的記憶體緩衝區常常鄰近重要的資料結構。現在假設某個函式的堆疊緊接在在記憶體緩衝區後面時,其中儲存的函式返回地址就會與記憶體緩衝區相鄰。

此時,惡意攻擊者就可以向記憶體緩衝區複製大量資料,從而使得記憶體緩衝區溢位並覆蓋原先儲存於堆疊中的函式返回地址。這樣,函式的返回地址就被攻擊者換成了他指定的數值;一旦函式呼叫完畢,就會繼續執行「函式返回地址」處的**。非但如此,c++ 的某些其它資料結構,比如 v-table 、例外事件處理程式、函式指標等,也可能受到類似的攻擊。

二、解決記憶體溢位問題

不要太悲觀,下面討論記憶體溢位問題的解決和預防措施。

1、改用受控**

2、遵守**規則

當你用 c/c++ 書寫**時,應該處處留意如何處理來自使用者的資料。如果一個函式的資料**不可靠,又用到記憶體緩衝區,那麼它就必須嚴格遵守下列規則:

必須知道記憶體緩衝區的總長度。

檢驗記憶體緩衝區。

提高警惕。

多型性,在c++中指具有不同功能的函式可以用同一個函式名,即可以用同一個函式名呼叫不同內容的函式。向不同的物件傳送用一個訊息,不同的物件在接收同樣的訊息,會產生不同的行為(方法)。

從系統實現角度來看。多型性分為兩類:靜態多型性和動態多型性。

靜態多型性:在程式編譯時系統就能決定呼叫哪個函式,因此靜態函式有稱編譯時的多型性(實質上是通過函式的過載實現)。例如:函式的過載和運算子過載實現.

動態多型性:執行過程中才動態地確定操作指標所指的物件。主要通過虛擬函式和重寫來實現。

2樓:

這個看在是什麼地方,就可以根據對應溢位原因進行避免比如char chr[10]=;

....

比如如果你這個變數用來裝輸入,或者從其他地方得到的值為了保險起見最好把記憶體開大點,當然如果知道大小最好,如果不知道最好開大點比如

char chr[1024]=;

另外比如有些api他會返回實際大小,這樣你可以根據他返回的大小來開記憶體.

3樓:鬼舞地帶**網

因int 型別的變數的大小隻有四個位元組,20的階乘太大了 所以溢位,把count改成 long long型就可以了。

#include

void main()

就是 long int , 也是四個位元組,和int 一樣 long long 是8個位元組的

4樓:匿名使用者

在填入或者拷貝前先進行判斷,確定不會引起溢位再填入

5樓:匿名使用者

那個方面的~_~!

知道它會溢位的話避免下不就好了麼?

如何解決棧溢位

6樓:生活類答題小能手

解決遞迴呼叫棧溢位的方法是通過尾遞迴優化,事實上尾遞迴和迴圈的效果是一樣的,所以,把迴圈看成是一種特殊的尾遞迴函式也是可以的。

尾遞迴,在函式返回的時候,呼叫自身本身,並且,return語句不能包含表示式。這樣,編譯器或者直譯器就可以把尾遞迴做優化,使遞迴本身無論呼叫多少次,都只佔用一個棧幀,不會出現棧溢位的情況。

擴充套件資料

針對堆疊溢位可能造成的電腦保安問題,通常有以下這些防範措施:

1、強制按照正確的規則寫**。

3、利用編譯器的邊界檢查來實現緩衝區的保護。該方法使得緩衝區溢位不可能出現,完全消除了緩衝區溢位的威脅,但代價較大,如效能速度變慢。

4、程式指標完整性檢查,該方法能阻止絕大多數緩衝區溢位攻擊。該方法就是說在程式使用指標之前,檢查指標的內容是否發生了變化。

c++棧溢位怎麼解決?

7樓:天蠍神經俠侶

說明遞迴層數過多(至少上萬了)

原因是寫的有問題,沒設定正確的退出條件;

也有可能是就是得遞迴那麼多層,這時可以考慮將函式遞迴改成利用std:stack實現遞迴,這樣能容忍的層數會多很多,只要記憶體夠。

叢程式是快速排序來看,更有可能是演算法寫錯了,導致遞迴無法終止。

8樓:匿名使用者

一般每個程序的棧空間是限定的。(為什麼限定?去學彙編和作業系統就知道)

什麼佔用棧空間?

除去系統棧佔用外,基本就是棧變數。(什麼是棧變數?無語¥%*&……%¥%&)

簡單來說上面那個a就是棧變數。

修改有兩個辦法:

一 改為堆變數:

int* pa = malloc(sizeof(int)*1000*1000);

然後可以將pa當陣列用。(陣列和指標在c裡基本等同)當然,不用了記得free pa。

二 修改系統限制

這個棧變數= 1000*1000*4 = 4m。(約等於)如果這個函式不頻繁呼叫,也不遞迴,一般還是可以接受。

可以修改作業系統對程序棧空間的大小限制,稍微調大一些。

ulimit檢視系統的限制。(*nix系統命令。不是windows的)

當然方法二非常不值得推薦

求教:c++中int轉long long計算過程溢位怎麼解決?

9樓:匿名使用者

(ll) (n / i) * (ll) (m / i); 的意思是先轉換成ll再相乘,結果是ll型別的,

(ll) ((n / i) * (m / i)) 的意思是按int型別相乘得出積,積為int型別,再轉為ll,這樣的話,問題就來了

雖然n/i 和m/i都在int範圍內,但是他們的積越界了

10樓:泰山

溢位是無法解決的, 因為int它就同有long long儲存的資料大. 如果int比long long還大, 那要long long的型別有什麼用呢?

11樓:酷哥

c++中的long long型資料的長度是int型的兩倍。

例如int型資料時32位,則long long型是64位;

解決方法:

1、先將int型資料轉為long型;

2、再將裝換後的long型資料裝換為longlong型。

c++中溢位時怎麼算

12樓:離離原上花開

溢位,如果你寫程式時,有邏輯錯誤,會報錯。計算超過某資料型別表示範圍,會顯示出錯,例如double 溢位會顯示1.#inf。

如果你需要處理超過計算機處理能力的某些大數運算,可採取相應的軟體技術。

例如大數階乘,大數乘法等。網上有不少相關資源。

13樓:匿名使用者

例如:short的表示範圍為65535,表示100000時溢位,計算100000-65535-1=實際表示範圍

14樓:匿名使用者

說清楚點啊,記憶體溢位還是陣列下標溢位,如果是陣列下標溢位的話,調整相應的維數就可以了,如果是記憶體溢位的話,那就要仔細找你new的物件啦,看看有沒有都釋放掉,不然留在堆記憶體裡遲早要溢位的o(∩_∩)o~

15樓:_小_蘇

除錯一下看是哪個地方出錯了。

如何解決超市排隊問題,超市如何解決收銀排隊問題

多增加幾個收銀臺啊就解決了,而且也增加就業崗位 刷手機。用來購物。和坐公汽一些方便 主要還是看工作人員的效率,有的排隊短的,服務員會讓排隊長的顧客過去 麥當勞也是這麼做過的 超市多了就不用排隊了!我看哪?你還是選一些避開人員高峰期的時候去!比如放棄自己吃飯的時間中午12 00的時候什麼的!1加強收銀...

如何解決mathtype相容,如何解決MathType相容Office

1 從mathtype安裝路徑中找到mathtype office support 64中的mathtype commands 6 for word 2013和wordcmds兩個檔案。此步驟要注意自己安裝的office2016版本是32位還是64位,32位使用者在mathtype office s...

如何解決CPU使用率過高問題,如何解決cpu使用率過高的問題

解決系統執行中cpu使用率過高的操作方法 一 禁用diagtrack diagnostics tracking service服務 首先在鍵盤上面 按專win r調出執行,輸入 services.msc 回車。在本地屬服務中找到diagtrack diagnostics tracking servi...