日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++堆栈溢出怎么解决_c语言进阶:堆栈原理揭秘

發布時間:2024/2/28 c/c++ 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++堆栈溢出怎么解决_c语言进阶:堆栈原理揭秘 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

學習C語言時,初學者常常被教材上一股腦拋出來的諸如“字符串”,“指針”,“鏈表”等概念搞得暈頭轉向,再加上教材重概念,輕運用的敘述方式,這些名稱就越發令人生畏。“堆棧”,“溢出”,“跑飛”也從本應很實用的概念變成了虛幻,令人難以捉摸的名詞。

其實這些C語言的概念就像瑞士軍刀上的一個個小組件,都是為了方便解決特定問題而設計的。接下來博主將嘗試用另一種打開方式,講解“堆棧(stack)”這把c語言的刀到底是為何被設計出來,又是為了方便切啥的。

目錄:

1. 什么是堆棧?

2. 為什么需要堆棧?

3. 堆棧的功能是怎么實現的?

4. Reference:

讓我們先重溫一下百度百科里,每一個字都看得懂,但是不知道在說什么的堆棧定義:

1. 什么是堆棧?

單片機應用中,堆棧是個特殊存儲區,堆棧屬于RAM空間的一部分,堆棧用于函數調用、中斷切換時保存和恢復現場數據。堆棧中的物體具有一個特性:第一個放入堆棧中的物體總是被最后拿出來, 這個特性通常稱為先進后出 (FILO—First-In/Last-Out)。 堆棧中定義了一些操作, 兩個最重要的是PUSH和POP。 PUSH(入棧)操作:堆棧指針(SP)加1,然后在堆棧的頂部加入一 個元素。POP(出棧)操作相反,出棧則先將SP所指示的內部ram單元中內容送入直接地址尋址的單元中(目的位置),然后再將堆棧指針(SP)減1。這兩種操作實現了數據項的插入和刪除。

接下來博主嘗試將百度百科試圖傳遞的信息翻譯為人話:

2. 為什么需要堆棧?

首先,為什么需要堆棧?真的是搞計算機的那幫宅男吃飽了撐的嗎?

【編者注:必須不是!魯迅曾經說過:“不想偷懶的程序員不是好程序員”,就算是吃撐了,程序員也只會是選擇來知乎摸魚】 其實每個看起來很玄乎的計算機概念,都是程序員為了以后能更方便的解決問題(偷懶)而提出的。

言歸正傳,堆棧其實是為了減少程序內存(RAM)占用的的問題而發明的。出于成本的考慮,單片機的內存容量一直都是非常有限的。而在單片機上電后,所有的變量又都需要被拷貝到內存中運行。為了解決這個矛盾,盡可能的節約代碼在運行過程中變量所占用的內存空間,“堆棧”和“局部變量”這兩個概念就被提了出來。其中“局部變量”從軟件的角度指出了某些變量只需要在特定的時間段【生存期】存在于單片機的內存中即可滿足程序正確運行的要求,而“堆棧”則從硬件的角度為程序員控制局部變量的生存期提供了便利。

3. 堆棧的功能是怎么實現的?

說的那么玄乎,堆棧和局部變量到底是怎么減少內存占用的呢?

3.1 軟件的角度:

從功能實現的角度講,函數實參和局部變量其實都可以用全局變量來實現。 但隨之而來會有幾個問題/缺點:

全局變量在程序執行的整個周期都存在,占用了大量的內存空間。有的變量明明就只被某個函數調用。既然這樣,對于這種變量,我能不能在函數用的時候聲明,調用完了就把它的內存空間釋放掉,讓給別的函數來用,這樣不就大大提高了內存的利用率了嗎,要知道單片機的RAM是很寶貴的。 想到這里,局部變量的概念就被發明了,即這些變量的生存周期只需要和對應的函數相同即可

【額外好處:由于局部變量在函數里面生成,所以函數copy到別的工程里面還能直接用,想想如果你把函數要用的變量聲明在函數外,那你copy的時候還要特意去找,多麻煩】

3.2 硬件的角度:

想法非常好,當年的科學家也是這么想的,但是每次都手動的用匯編指令去創建,刪除變量好麻煩!程序員也是人啊,于是為了擺脫繁瑣的重復勞動,棧被發明了出來。棧并不是一個純粹抽象的軟件概念,而是由包括esp,ebp這些實際存在的堆棧寄存器來支撐的。

下面講解這兩個寄存器是如何將局部變量的創建和刪除自動化起來,從而節約了程序員大量時間的:

Esp寄存器:存儲棧頂地址

Ebp寄存器: 存儲棧基地址

Esp到ebp地址之間被視為當前函數的棧空間,聲明變量時,根據局部變量的大小,將堆棧寄存器esp的值下移,即可留出對應的空間用于存儲該變量。而刪除時,只需要將當前ebp的值賦給esp【即將棧頂指針直接壓倒棧底】,即可自動將所有與該函數相關的局部變量清空,將所占用空間釋放。一條指令,統一管理,統一釋放,美滋滋!

最后總結一下,在相較于上古時期手動創建,刪除全局變量來實現節約內存的無奈之舉,通過堆棧實現局部變量的管理有一下優點:

  • 地址空間連續,沒有碎片化,利用率高
  • 有專門的寄存器幫助,管理方便,push,pop一鍵刪除
  • 生存周期短,函數沒了就釋放,所以同一RAM空間可以反復被不同函數使用
  • 因為有了局部變量的概念,就基本杜絕了其他函數誤操作局部變量的可能,除非使用指針
  • 媽媽再也不用擔心變量重名了
  • 4. Reference:

    http://c.biancheng.net/view/3634.html

    總結

    以上是生活随笔為你收集整理的c++堆栈溢出怎么解决_c语言进阶:堆栈原理揭秘的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。