為什麼不能在函式中申請大陣列?

2022-08-23 04:42:10 字數 1556 閱讀 4309

1. 簡而言之,陣列定義在函式中時,占用的記憶體來自棧空間,棧空間是在程序建立時初始化的,有固定的大小,一般很小,所以太大的陣列會耗光棧空間。全域性變數一般分配在資料段,可以比較大。

2.bbs段、資料段、**段、堆與棧及5大記憶體分配

bss段(block started by symbol):

bss段(bss segment)通常是指用來存放程式中未初始化的全域性變數的一塊記憶體區域。bss段屬於靜態記憶體分配。

資料段:

資料段(data segment)通常是指用來存放程式中已初始化的全域性變數的一塊記憶體區域。資料段屬於靜態記憶體分配。

**段:

**段(code segment/text segment)通常是指用來存放程式執行**的一塊記憶體區域。這部分區域的大小在程式執行前就已經確定,並且記憶體區域通常屬於唯讀, 某些架構也允許**段為可寫,即允許修改程式。在**段中,也有可能包含一些唯讀的常數變數,例如字串常量等。

堆(heap):

堆是用於存放程序執行中被動態分配的記憶體段,它的大小並不固定,可動態擴張或縮減。當程序呼叫malloc等函式分配記憶體時,新分配的記憶體就被動態新增到堆上(堆被擴張);當利用free等函式釋放記憶體時,被釋放的記憶體從堆中被剔除(堆被縮減)

棧(stack):

棧又稱堆疊, 是使用者存放程式臨時建立的區域性變數,也就是說我們函式括弧「{}」中定義的變數(但不包括static宣告的變數,static意味著在資料段中存放變數)。除此以外,在函式被呼叫時,其引數也會被壓入發起呼叫的程序棧中,並且待到呼叫結束後,函式的返回值也會被存放回棧中。由於棧的先進後出特點,所以棧特別方便用來儲存/恢復呼叫現場。從這個意義上講,我們可以把堆疊看成乙個寄存、交換臨時資料的記憶體區。

5大區:

1、棧區(stack)— 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。 

2、堆區(heap) — 一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由os** 。它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶。 

3、全域性區(靜態區)(static)—全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域, 未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域, 程式結束後有系統釋放 。

4、文字常量區—常量字串就是放在這裡的,程式結束後由系統釋放 。

5、程式**區—存放函式體的二進位制**。

3.大小

在windows下,棧是向低位址擴充套件的資料結構,是一塊連續的記憶體區域。棧頂的位址和棧的最大容量是系統預先規定好的,在window下,棧的大小是2mb,linux下,預設棧空間大小為8mb,可通過ulimit -s來設定。

堆是向高位址擴充套件的資料結構,是不連續的記憶體區域。這是由於系統是用鍊錶來儲存空閒記憶體位址的,自然是不連續的,而鍊錶的便利方向是由低位址向高位址的。在window下,棧的大小一般小於2gb。

為什麼不能在建構函式中使用虛函式

先上 c datastructure.cpp 定義控制台應用程式的入口點。此時發揮作用的是base fun 而不是派生類a fun 也就是虛函式在建構函式中不起作用。當例項化乙個派生類物件時,首先進行基類部分的構造,然後再進行派生類部分的構造。即建立a物件時,會先呼叫base的建構函式,再呼叫a的建...

為什麼不能在增強for中刪除集合的元素

學習的過程中遇到的乙個問題,下述 在嘗試remove其他元素的時候會出現異常,而在remove最後乙個元素的時候,可以正常執行.public class main 初步查詢後得知,增強for和迭代器遍歷的過程中,直接用集合去remove以及其他修改集合的操作很容易出現問題.之後debug 翻原始碼分...

為什麼不能在ISR中進行任務切換

吾日三省吾身 為人謀而不忠乎?與朋友交而不信乎?傳不習乎?在學習ucosiii的時候時常遇到下面的一段 能看懂,它的意思就是不允許在中斷中進行任務排程,但是就是不知道為什麼要這樣設定,今天仔細想了一下,同時上網搜了一下,得到答案 如果我們在中斷中切換到別的地方去執行,由於isr並沒有向作業系統核心報...