亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

c++內存分配說明及mysql常見內存分配操作

2023-12-07 02:05:03
19
0

c++內存分配說明及mysql常見內存分配操作

1 內存分配相關知識點

1.1 基本內存知識

什么是內存 ? 一個C/C++編譯的程序占用內存分為以下幾個部分:

棧區(stack):由 編譯器自動分配和釋放, 存放的是 運行時函數分配的局部變量,函數參數,返回數據,返回地址等參數,其操作類似于數據結構中的

 

堆區(heap):由 由程序員手動分配, 一般存放的是 保存動態分配的變量和對象。堆區上的內存分配和釋放是由程序員顯式控制的。如果程序員沒有釋放,程序結束時可能由os回收,其分配類似于鏈表

 

全局區(靜態區static)存放全局變量,靜態數據,常量。程序結束后由系統釋放,全局區分為已初始化全局區(data)和未初始化全局區(bss)。

 

常量區(文字常量區):存放的是 常量字符串。程序結束后由系統釋放

 

代碼區:存放的是 函數體(類成員函數和全局區)的二進制代碼。程序結束后由系統釋放

 

 

?? 三種內存分配方式:

一.從靜態存儲區分配內存 從靜態存儲區分配的內存在 程序編譯的時候就已經被分配完畢了,這塊內存在程序的整個運行期間都會存在(例如全局變量,static變量)。

二.在棧上創建內存空間 在執行函數時, 函數內局部變量的存儲單元可以在棧上創建,函數執行結束的時候,這些內存單元會自動被釋放,棧內存分配運算內置于處理器的指令集,效率高,但是 分配的內存容量有限

三.在堆上分配內存(動態內存分配)?????? 在堆上分配內存亦被稱為動態分配內存,程序在運行的時候使用malloc或者new申請 任意大小的內存,程序員自己負責在何時使用free和delete進行動態分配的內存的釋放。 動態內存的生命周期是由程序員決定的,而且動態內存的申請和釋放的使用過程非常靈活,but!如果在堆上分配了空間,則必須對堆上分配的內存進行回收,因為系統是無權對堆上的內存進行管理的,若只是申請了動態內存卻不對內存進行釋放,程序將會出現內存泄漏(OOM),且 頻繁的分配和釋放不同大小的堆空間將產生內存碎片

 

內存分配的簡易示意圖:

 

靜態全局數據區:存放全局數據和靜態數據 代碼段:存放可執行代碼只讀常量 堆區:存放動態開辟的變量 棧區:非靜態局部變量、函數參數,返回值等:存放全局數據和靜態數據

在內存的角度來講,堆和棧的區別:

管理方式不同:棧由編譯器自動申請和釋放空間,堆需要程序員手動申請和釋放空間。

空間大小不同:棧的空間有限,32位平臺下,VC6下默認為1M,而堆最大可以達到4G。

能否產生碎片: 棧和數據結構中的棧原理相同,在彈出一個元素之前,上一個元素已經彈出了,所以不會產生碎片,但如果不停的進行動態內存的申請和釋放則會積累很多內存碎片。

生長方向的不同:堆的生長方向是向上的,也就是向著內存地址增加的方向,而棧剛好是相反的,棧是向著內存減小的方向生長的(因為棧的空間十分有限,所以棧是從上限往棧的下限生長的)

分配的方式不同:堆都是動態分配的,沒有靜態能進行分配的堆。而棧有靜態分配和動態分配兩種分配方式。靜態分配是編譯器完成的,比如局部變量的分配,動態分配在C++中由new函數進行分配。請注意:棧的動態分配和堆的是不同的,棧的動態分配由編譯器進行釋放,無需使用delete進行釋放。

分配的效率不同:棧的效率比堆要高很多,因為棧是機器系統提供的數據結構,計算機在底層提供了棧的支持,分配專門的寄存器來存放棧的地址,壓棧和出棧都有相應的指令,因此棧在分配的效率上是一定比堆上快的。而堆是由庫函數提供的,機制很復雜,庫函數會按照一定的算法進行搜索內存,因此比較慢

棧中內存的申請和釋放: 通常來說,一個線程上的棧內存是有限的,通常為8MB左右(大小取決于運行環境),棧上的內存通常是由編譯器自動管理的。當在棧上分配一個新的變量時,或進入一個函數時,棧的指針會向下移動(下壓棧),相當于在棧上分配了一塊內存。我們把變量分配在棧上,也就是利用了棧上的內存空間,當這個變量的生命周期結束的時候,棧的指針會上移,相當于回收了此塊內存。

正是由于棧上的內存和分配和回收均是由編譯器自動完成控制的,所以在上是不會發生內存泄漏的,只會發生棧 溢 出的情況(Stack Overflow),也就是分配的空間超過了規定的棧大小。

堆中內存的申請和釋放: 堆中的內存是由程序直接控制的,程序可以通過[new/delete]來分配和回收內存,如果程序中通過[new]手動分配了一塊內存,但忘記使用[delete]來回收內存,便會發生內存泄漏

 

靜態全局變量(static),全局變量,靜態局部變量(static),局部變量的區別:

靜態全局變量和全局變量的區別: 1.靜態全局變量和全局變量 都屬于常量區 2.靜態全局區 只在本文件中有效,別的文件如果向調用該變量,是調用不了的,且全局變量在別的文件中還可以調用。 3.如果別的文件中定義了一個該全局變量相同的的變量名,是會出錯的。

靜態局部變量和局部變量的區別: 1.靜態局部變量是屬于常量區的,而函數內部的局部變量屬于棧區。 2.靜態局部變量在該函數調用結束的時候,不會銷毀,而是隨著整個程序的結束而結束,靜態局部變量不能被此函數外的函數調用。局部變量也是隨著該函數的結束而結束的。 3.如果定義這兩個變量的時候沒有賦初始值,那么靜態局部變量會自動的定義為0,而局部變量就是一個隨機的值(一般的編譯器會強制要求局部變量必須進行賦初值 而靜態局部變量是否賦初值則不做強制性要求)。 4.靜態局部變量在編譯期間只賦值一次,以后每次調用函數時,不再賦值,而是直接調用上次的函數調用結束時的值。而局部變量在調用期間,每調用一次,便會對這個局部變量進行重新賦值

 

也就是說局部變量沒有記憶性,每次到函數中,他都從最開始的狀態執行,但是靜態局部變量有記憶性,每次到函數中,它記得住上一次結束是它的值,這一次運行從上一次結束的狀態執行。

總結:?? 全局變量:可以被本程序所有對象或函數引用. 靜態全局變量:是在全局變量聲明前加上一個static關鍵字,使該變量只能在這個源文件可用. 局部變量:只能被函數內部引用,而無法被其他的對象或函數引用. 靜態局部變量:通常放在函數內部,只能在函數內部被調用,只進行一次初始化,每次執行函數時保持上一次執行的值.

 

1.2 C/C++內存分配常見操作

1.2.1 sizeof

在C與C++中,內存的分配是以字節為單位進行分配的。sizeof也是統計的字節數。

例如:

??array_elements宏定義(mysql5.7源碼)

#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))

就是用整個A數組的字節數/A[0]的字節數,那么結果就是整個數組的元素個數。

 

1.2.2 mysql_memory_register宏

#define mysql_memory_register(P1, P2, P3) \
inline_mysql_memory_register(P1, P2, P3)

mysql_memory_register內聯了inline_mysql_memory_register函數,它的作用是注冊 MySQL 5.7 版本中的內存信息,注冊內存信息是為了實現內存管理和性能分析。在一個大型的軟件系統中,準確地了解內存的分配和釋放情況對于性能優化、內存泄漏檢測和資源管理都非常重要。通過注冊內存信息,可以跟蹤和監控內存的使用情況,從而更好地管理系統的資源。

這個宏有三個參數

  • category(p1):表示內存分配的類別,可以用于對不同類型的內存分配進行分類。當編譯時啟用了 HAVE_PSI_MEMORY_INTERFACE 宏時,這個參數會被使用。

  • info(p2):表示一個指向 PSI_memory_info 結構的指針,用于存儲內存信息。當編譯時啟用了 HAVE_PSI_MEMORY_INTERFACE 宏時,這個參數會被使用。

  • count(p3):表示要注冊的內存塊數量。

??這里可以學到一個方法,如果一個函數想只讓它在這個文件中生效,如何做?用statci關鍵字。但是如果其他外部文件要用怎么辦?用inline關鍵字 + 一個宏內聯到它

 

例如:

mysql_memory_register(AUDIT_LOG_PSI_CATEGORY, all_audit_log_memory, count);

分配了 count 個內存塊,存儲的信息放到 all_audit_log_memory 中,內存分配的類別是 AUDIT_LOG_PSI_CATEGORY。

mysql_memory_register 宏和 my_malloc 函數區別

  1. mysql_memory_register 宏:

    • 這是 MySQL 中的一個宏,用于將內存分配注冊到內存統計和分析接口(PSI,Performance Schema Instrumentation)中,以便在性能分析和監控中能夠追蹤內存的使用情況。

    • 它通常在 MySQL 代碼中用于分配一些特定的內存資源,比如分配內存池、內存緩沖區等等。

    • 通過注冊到 PSI 接口,可以跟蹤內存的分配和釋放,以便進行性能分析和優化。

  2. my_malloc 函數:

    • my_malloc 是 MySQL 中的一個函數,用于分配內存塊。

    • 它是直接的內存分配函數,用于分配一塊指定大小的內存,并返回內存塊的指針。

    • malloc 函數類似,my_malloc 用于一般的內存分配需求。

總之,mysql_memory_register 宏主要用于將內存分配注冊到性能統計接口中,以進行性能監控和分析,而 my_malloc 函數是用于一般的內存分配操作。它們可以在不同的場景和需求下使用。

 

1.2.3 my_hash_init宏

my_hash_init 宏來初始化一個哈希表(hash table)

例如

my_hash_init(&exclude_commands, &my_charset_bin,
20, 0, 0,
(my_hash_get_key) command_get_key,
my_free, HASH_UNIQUE, key_memory_audit_log_commands);
  1. &exclude_commands:這是一個指向 my_hash_t 結構的指針,表示要初始化的哈希表對象。

  2. &my_charset_bin:這是一個指向字符集(character set)的指針,用于指定在哈希表中存儲的字符數據的字符集。

  3. 20:這是哈希表的初始桶數(bucket count),即哈希表內部存儲數據的存儲桶數量。這個值通常會影響哈希表的性能和內存占用,較大的值可能會降低哈希沖突。

  4. 0:這是一個保留參數,通常用于將來的擴展或其他用途。在您提供的代碼中,沒有使用這個參數。

  5. 0:這是一個保留參數,通常用于將來的擴展或其他用途。在您提供的代碼中,沒有使用這個參數。

  6. (my_hash_get_key) command_get_key:這是一個函數指針,指向一個函數,用于計算存儲在哈希表中的鍵(key)的哈希值。在您提供的代碼中,command_get_key 函數用于計算哈希鍵的哈希值。

  7. my_free:這是一個用于釋放內存的函數指針,用于在哈希表刪除數據時釋放相應的內存資源。

  8. HASH_UNIQUE:這是一個標志,用于指定哈希表中的鍵是否應該是唯一的。HASH_UNIQUE 表示鍵是唯一的,重復的鍵將不會被插入到哈希表中。

  9. key_memory_audit_log_commands:這是一個字符串,表示用于哈希鍵的內存池標識符,用于在哈希表中分配鍵的內存。

這里也可以學到一個方法一般哈希表的鍵值,可以就存它的name,value值存它的長度,這樣,length(只保存數據用)可以一樣,但是name是不一樣的。

 

1.2.4 棧幀

棧幀(Stack Frame)是用于支持函數調用和返回的一種數據結構。每次調用函數時,系統會為該函數分配一個棧幀,棧幀中存儲了函數的局部變量、參數、返回地址以及其他與函數調用相關的信息。當函數執行完畢后,棧幀會被釋放,以便返回到調用函數的上下文。

棧幀通常包括以下幾個重要的部分:

  1. 局部變量區域(Local Variables Area):用于存儲函數中定義的局部變量。局部變量只在函數內部可見,函數調用結束后會自動銷毀。

  2. 參數區域(Arguments Area):用于存儲函數調用時傳遞的參數。這些參數可以是函數的輸入,供函數在執行時使用。

  3. 返回地址(Return Address):用于存儲函數執行完畢后要返回的位置。當函數執行完畢時,程序會從返回地址處繼續執行。

  4. 調用者的幀指針(Caller's Frame Pointer):指向調用函數的棧幀。它可以用來訪問調用函數的局部變量和參數。

  5. 其他上下文信息:可能包括存儲寄存器的值、狀態信息等。

棧幀的創建和銷毀是通過棧(Stack)數據結構來管理的。棧是一種后進先出(Last-In-First-Out,LIFO)的數據結構,適用于函數調用和返回的特性。當函數被調用時,系統將新的棧幀壓入棧頂,當函數返回時,對應的棧幀會被彈出。

棧幀的概念在程序執行和調試過程中起著重要的作用,它使得函數的嵌套調用能夠正確地保存和恢復上下文信息,保證程序的正確執行和控制流的正確性。

 

 
0條評論
0 / 1000
張凡
7文章數
0粉絲數
張凡
7 文章 | 0 粉絲
原創

c++內存分配說明及mysql常見內存分配操作

2023-12-07 02:05:03
19
0

c++內存分配說明及mysql常見內存分配操作

1 內存分配相關知識點

1.1 基本內存知識

什么是內存 ? 一個C/C++編譯的程序占用內存分為以下幾個部分:

棧區(stack):由 編譯器自動分配和釋放, 存放的是 運行時函數分配的局部變量,函數參數,返回數據,返回地址等參數,其操作類似于數據結構中的

 

堆區(heap):由 由程序員手動分配, 一般存放的是 保存動態分配的變量和對象。堆區上的內存分配和釋放是由程序員顯式控制的。如果程序員沒有釋放,程序結束時可能由os回收,其分配類似于鏈表

 

全局區(靜態區static)存放全局變量,靜態數據,常量。程序結束后由系統釋放,全局區分為已初始化全局區(data)和未初始化全局區(bss)。

 

常量區(文字常量區):存放的是 常量字符串。程序結束后由系統釋放

 

代碼區:存放的是 函數體(類成員函數和全局區)的二進制代碼。程序結束后由系統釋放

 

 

?? 三種內存分配方式:

一.從靜態存儲區分配內存 從靜態存儲區分配的內存在 程序編譯的時候就已經被分配完畢了,這塊內存在程序的整個運行期間都會存在(例如全局變量,static變量)。

二.在棧上創建內存空間 在執行函數時, 函數內局部變量的存儲單元可以在棧上創建,函數執行結束的時候,這些內存單元會自動被釋放,棧內存分配運算內置于處理器的指令集,效率高,但是 分配的內存容量有限

三.在堆上分配內存(動態內存分配)?????? 在堆上分配內存亦被稱為動態分配內存,程序在運行的時候使用malloc或者new申請 任意大小的內存,程序員自己負責在何時使用free和delete進行動態分配的內存的釋放。 動態內存的生命周期是由程序員決定的,而且動態內存的申請和釋放的使用過程非常靈活,but!如果在堆上分配了空間,則必須對堆上分配的內存進行回收,因為系統是無權對堆上的內存進行管理的,若只是申請了動態內存卻不對內存進行釋放,程序將會出現內存泄漏(OOM),且 頻繁的分配和釋放不同大小的堆空間將產生內存碎片

 

內存分配的簡易示意圖:

 

靜態全局數據區:存放全局數據和靜態數據 代碼段:存放可執行代碼只讀常量 堆區:存放動態開辟的變量 棧區:非靜態局部變量、函數參數,返回值等:存放全局數據和靜態數據

在內存的角度來講,堆和棧的區別:

管理方式不同:棧由編譯器自動申請和釋放空間,堆需要程序員手動申請和釋放空間。

空間大小不同:棧的空間有限,32位平臺下,VC6下默認為1M,而堆最大可以達到4G。

能否產生碎片: 棧和數據結構中的棧原理相同,在彈出一個元素之前,上一個元素已經彈出了,所以不會產生碎片,但如果不停的進行動態內存的申請和釋放則會積累很多內存碎片。

生長方向的不同:堆的生長方向是向上的,也就是向著內存地址增加的方向,而棧剛好是相反的,棧是向著內存減小的方向生長的(因為棧的空間十分有限,所以棧是從上限往棧的下限生長的)

分配的方式不同:堆都是動態分配的,沒有靜態能進行分配的堆。而棧有靜態分配和動態分配兩種分配方式。靜態分配是編譯器完成的,比如局部變量的分配,動態分配在C++中由new函數進行分配。請注意:棧的動態分配和堆的是不同的,棧的動態分配由編譯器進行釋放,無需使用delete進行釋放。

分配的效率不同:棧的效率比堆要高很多,因為棧是機器系統提供的數據結構,計算機在底層提供了棧的支持,分配專門的寄存器來存放棧的地址,壓棧和出棧都有相應的指令,因此棧在分配的效率上是一定比堆上快的。而堆是由庫函數提供的,機制很復雜,庫函數會按照一定的算法進行搜索內存,因此比較慢

棧中內存的申請和釋放: 通常來說,一個線程上的棧內存是有限的,通常為8MB左右(大小取決于運行環境),棧上的內存通常是由編譯器自動管理的。當在棧上分配一個新的變量時,或進入一個函數時,棧的指針會向下移動(下壓棧),相當于在棧上分配了一塊內存。我們把變量分配在棧上,也就是利用了棧上的內存空間,當這個變量的生命周期結束的時候,棧的指針會上移,相當于回收了此塊內存。

正是由于棧上的內存和分配和回收均是由編譯器自動完成控制的,所以在上是不會發生內存泄漏的,只會發生棧 溢 出的情況(Stack Overflow),也就是分配的空間超過了規定的棧大小。

堆中內存的申請和釋放: 堆中的內存是由程序直接控制的,程序可以通過[new/delete]來分配和回收內存,如果程序中通過[new]手動分配了一塊內存,但忘記使用[delete]來回收內存,便會發生內存泄漏

 

靜態全局變量(static),全局變量,靜態局部變量(static),局部變量的區別:

靜態全局變量和全局變量的區別: 1.靜態全局變量和全局變量 都屬于常量區 2.靜態全局區 只在本文件中有效,別的文件如果向調用該變量,是調用不了的,且全局變量在別的文件中還可以調用。 3.如果別的文件中定義了一個該全局變量相同的的變量名,是會出錯的。

靜態局部變量和局部變量的區別: 1.靜態局部變量是屬于常量區的,而函數內部的局部變量屬于棧區。 2.靜態局部變量在該函數調用結束的時候,不會銷毀,而是隨著整個程序的結束而結束,靜態局部變量不能被此函數外的函數調用。局部變量也是隨著該函數的結束而結束的。 3.如果定義這兩個變量的時候沒有賦初始值,那么靜態局部變量會自動的定義為0,而局部變量就是一個隨機的值(一般的編譯器會強制要求局部變量必須進行賦初值 而靜態局部變量是否賦初值則不做強制性要求)。 4.靜態局部變量在編譯期間只賦值一次,以后每次調用函數時,不再賦值,而是直接調用上次的函數調用結束時的值。而局部變量在調用期間,每調用一次,便會對這個局部變量進行重新賦值

 

也就是說局部變量沒有記憶性,每次到函數中,他都從最開始的狀態執行,但是靜態局部變量有記憶性,每次到函數中,它記得住上一次結束是它的值,這一次運行從上一次結束的狀態執行。

總結:?? 全局變量:可以被本程序所有對象或函數引用. 靜態全局變量:是在全局變量聲明前加上一個static關鍵字,使該變量只能在這個源文件可用. 局部變量:只能被函數內部引用,而無法被其他的對象或函數引用. 靜態局部變量:通常放在函數內部,只能在函數內部被調用,只進行一次初始化,每次執行函數時保持上一次執行的值.

 

1.2 C/C++內存分配常見操作

1.2.1 sizeof

在C與C++中,內存的分配是以字節為單位進行分配的。sizeof也是統計的字節數。

例如:

??array_elements宏定義(mysql5.7源碼)

#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))

就是用整個A數組的字節數/A[0]的字節數,那么結果就是整個數組的元素個數。

 

1.2.2 mysql_memory_register宏

#define mysql_memory_register(P1, P2, P3) \
inline_mysql_memory_register(P1, P2, P3)

mysql_memory_register內聯了inline_mysql_memory_register函數,它的作用是注冊 MySQL 5.7 版本中的內存信息,注冊內存信息是為了實現內存管理和性能分析。在一個大型的軟件系統中,準確地了解內存的分配和釋放情況對于性能優化、內存泄漏檢測和資源管理都非常重要。通過注冊內存信息,可以跟蹤和監控內存的使用情況,從而更好地管理系統的資源。

這個宏有三個參數

  • category(p1):表示內存分配的類別,可以用于對不同類型的內存分配進行分類。當編譯時啟用了 HAVE_PSI_MEMORY_INTERFACE 宏時,這個參數會被使用。

  • info(p2):表示一個指向 PSI_memory_info 結構的指針,用于存儲內存信息。當編譯時啟用了 HAVE_PSI_MEMORY_INTERFACE 宏時,這個參數會被使用。

  • count(p3):表示要注冊的內存塊數量。

??這里可以學到一個方法,如果一個函數想只讓它在這個文件中生效,如何做?用statci關鍵字。但是如果其他外部文件要用怎么辦?用inline關鍵字 + 一個宏內聯到它

 

例如:

mysql_memory_register(AUDIT_LOG_PSI_CATEGORY, all_audit_log_memory, count);

分配了 count 個內存塊,存儲的信息放到 all_audit_log_memory 中,內存分配的類別是 AUDIT_LOG_PSI_CATEGORY。

mysql_memory_register 宏和 my_malloc 函數區別

  1. mysql_memory_register 宏:

    • 這是 MySQL 中的一個宏,用于將內存分配注冊到內存統計和分析接口(PSI,Performance Schema Instrumentation)中,以便在性能分析和監控中能夠追蹤內存的使用情況。

    • 它通常在 MySQL 代碼中用于分配一些特定的內存資源,比如分配內存池、內存緩沖區等等。

    • 通過注冊到 PSI 接口,可以跟蹤內存的分配和釋放,以便進行性能分析和優化。

  2. my_malloc 函數:

    • my_malloc 是 MySQL 中的一個函數,用于分配內存塊。

    • 它是直接的內存分配函數,用于分配一塊指定大小的內存,并返回內存塊的指針。

    • malloc 函數類似,my_malloc 用于一般的內存分配需求。

總之,mysql_memory_register 宏主要用于將內存分配注冊到性能統計接口中,以進行性能監控和分析,而 my_malloc 函數是用于一般的內存分配操作。它們可以在不同的場景和需求下使用。

 

1.2.3 my_hash_init宏

my_hash_init 宏來初始化一個哈希表(hash table)

例如

my_hash_init(&exclude_commands, &my_charset_bin,
20, 0, 0,
(my_hash_get_key) command_get_key,
my_free, HASH_UNIQUE, key_memory_audit_log_commands);
  1. &exclude_commands:這是一個指向 my_hash_t 結構的指針,表示要初始化的哈希表對象。

  2. &my_charset_bin:這是一個指向字符集(character set)的指針,用于指定在哈希表中存儲的字符數據的字符集。

  3. 20:這是哈希表的初始桶數(bucket count),即哈希表內部存儲數據的存儲桶數量。這個值通常會影響哈希表的性能和內存占用,較大的值可能會降低哈希沖突。

  4. 0:這是一個保留參數,通常用于將來的擴展或其他用途。在您提供的代碼中,沒有使用這個參數。

  5. 0:這是一個保留參數,通常用于將來的擴展或其他用途。在您提供的代碼中,沒有使用這個參數。

  6. (my_hash_get_key) command_get_key:這是一個函數指針,指向一個函數,用于計算存儲在哈希表中的鍵(key)的哈希值。在您提供的代碼中,command_get_key 函數用于計算哈希鍵的哈希值。

  7. my_free:這是一個用于釋放內存的函數指針,用于在哈希表刪除數據時釋放相應的內存資源。

  8. HASH_UNIQUE:這是一個標志,用于指定哈希表中的鍵是否應該是唯一的。HASH_UNIQUE 表示鍵是唯一的,重復的鍵將不會被插入到哈希表中。

  9. key_memory_audit_log_commands:這是一個字符串,表示用于哈希鍵的內存池標識符,用于在哈希表中分配鍵的內存。

這里也可以學到一個方法一般哈希表的鍵值,可以就存它的name,value值存它的長度,這樣,length(只保存數據用)可以一樣,但是name是不一樣的。

 

1.2.4 棧幀

棧幀(Stack Frame)是用于支持函數調用和返回的一種數據結構。每次調用函數時,系統會為該函數分配一個棧幀,棧幀中存儲了函數的局部變量、參數、返回地址以及其他與函數調用相關的信息。當函數執行完畢后,棧幀會被釋放,以便返回到調用函數的上下文。

棧幀通常包括以下幾個重要的部分:

  1. 局部變量區域(Local Variables Area):用于存儲函數中定義的局部變量。局部變量只在函數內部可見,函數調用結束后會自動銷毀。

  2. 參數區域(Arguments Area):用于存儲函數調用時傳遞的參數。這些參數可以是函數的輸入,供函數在執行時使用。

  3. 返回地址(Return Address):用于存儲函數執行完畢后要返回的位置。當函數執行完畢時,程序會從返回地址處繼續執行。

  4. 調用者的幀指針(Caller's Frame Pointer):指向調用函數的棧幀。它可以用來訪問調用函數的局部變量和參數。

  5. 其他上下文信息:可能包括存儲寄存器的值、狀態信息等。

棧幀的創建和銷毀是通過棧(Stack)數據結構來管理的。棧是一種后進先出(Last-In-First-Out,LIFO)的數據結構,適用于函數調用和返回的特性。當函數被調用時,系統將新的棧幀壓入棧頂,當函數返回時,對應的棧幀會被彈出。

棧幀的概念在程序執行和調試過程中起著重要的作用,它使得函數的嵌套調用能夠正確地保存和恢復上下文信息,保證程序的正確執行和控制流的正確性。

 

 
文章來自個人專欄
文章 | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0