c 記憶體分配中乙個有趣的小問題

2022-03-11 02:53:14 字數 1223 閱讀 8655

[toc]

以下**測試環境:**vs2019**

## 問題的提出

執行這麼一段**,看看會發生什麼:

```c++

int arr[5] = ;

int main()

```毫無疑問,會報錯,因為訪問越界了。

***再看看另一段**:

```c++

int arr[5] = ;

int main()

```與上面的**相比幾乎沒什麼差別,僅僅把arr的定義和初始化搬到了函式外面,但執行程式卻沒有出錯。

類似的還有這麼一段**:

```c++

int main()

;arr[5] = 1;

}```

同樣也能執行成功,那麼這是為什麼呢?

## 問題的探索

[以下這段話摘自](

>在`c++`中記憶體分為5個區,分別是**堆**、**棧**、**自由儲存區**、**全域性/靜態儲存區**和**常量儲存區**。

>**堆**:**堆**是作業系統中的術語,是作業系統所維護的一塊特殊記憶體,用於程式的記憶體動態分配,`c`語言使用`malloc`從堆上分配記憶體,使用`free`釋放已分配的對應記憶體。

>**棧**:在執行函式時,函式內區域性變數的儲存單元都可以在**棧**上建立,函式執行結束時這些儲存單元自動被釋放。**棧**記憶體分配運算內置於處理器的指令集中,效率很高,但是分配的記憶體容量有限。

>**自由儲存區**:**自由儲存區**是`c++`基於`new`操作符的乙個抽象概念,凡是通過`new`操作符進行記憶體申請,該記憶體即為**自由儲存區**。

>**全域性/靜態儲存區**:這塊記憶體是在程式編譯的時候就已經分配好的,在程式整個執行期間都存在。例如*全域性變數*,*靜態變數*。

>**常量儲存區**:這是一塊比較特殊的儲存區,他們裡面存放的是`常量(const)`,不允許修改。

上面的問題涉及到兩個區:**棧**和**全域性/靜態儲存區**。

## 個人的推測

基於以上結果,我有個不成熟的小推測:

+ **棧**的空間是系統預定分配好的,假如我定義了`int arr[5]`,那麼系統就一定給我5*4(32位系統下)個位元組的空間,系統**不允許**我訪問超過這個空間的位址上的資料。

+ **全域性/靜態儲存區**則不同,當我定義`int arr[5]`時,系統給我返回`arr`的**首位址**,我不僅可以根據這個首位址去訪問20個位元組的內容,還可以訪問這二十個位元組以外的內容。

彙編中乙個有趣的問題

int main 問題是下面哪個關係成立 a b c還是 a b c?我們知道區域性變數是存放在棧中的,a先push,然後是b,最後是c。而棧指標sp是從高位址 低位址方向移動的,所以 a b c。如果void f int a int b,int c 這裡就是 a b c,因為引數是逆序進棧的。網上...

彙編中乙個有趣的問題

intmain 問題是下面哪個關係成立 a b c還是 a b c?我們知道區域性變數是存放在棧中的,a先push,然後是b,最後是c。而棧指標sp是從高位址 低位址方向移動的,所以 a b c。如果void f int a int b,int c 這裡就是 a b c,因為引數是逆序進棧的。網上有...

C中乙個有趣的列印

在lresult sendmessage hwnd hwnd,handle of destination window uint msg,message to send wparam wparam,first message parameter lparam lparam second messag...