網站首頁 編程語言 正文
內存分布
程序沒有加載到內存前,可執行程序內部已經分好3段信息,分別為代碼區(text)、數據區(data)和未初始化數據區(bss)3 個部分(有些人直接把data和bss合起來叫做靜態區或全局區)。
代碼區
存放 CPU 執行的機器指令。通常代碼區是可共享的(即另外的執行程序可以調用它),使其可共享的目的是對于頻繁被執行的程序,只需要在內存中有一份代碼即可。代碼區通常是只讀的,使其只讀的原因是防止程序意外地修改了它的指令。另外,代碼區還規劃了局部變量的相關信息。
全局初始化數據區/靜態數據區(data段)
該區包含了在程序中明確被初始化的全局變量、已經初始化的靜態變量(包括全局靜態變量和局部靜態變量)和常量數據(如字符串常量)。
未初始化數據區(又叫 bss 區)
存入的是全局未初始化變量和未初始化靜態變量。未初始化數據區的數據在程序開始執行之前被內核初始化為 0 或者空(NULL)。
程序在加載到內存前,代碼區和全局區(data和bss)的大小就是固定的,程序運行期間不能改變。然后,運行可執行程序,系統把程序加載到內存,除了根據可執行程序的信息分出代碼區(text)、數據區(data)和未初始化數據區(bss)之外,還額外增加了棧區、堆區。
代碼區(text segment)
加載的是可執行文件代碼段,所有的可執行代碼都加載到代碼區,這塊內存是不可以在運行期間修改的。
未初始化數據區(BSS)
加載的是可執行文件BSS段,位置可以分開亦可以緊靠數據段,存儲于數據段的數據(全局未初始化,靜態未初始化數據)的生存周期為整個程序運行過程。
全局初始化數據區/靜態數據區(data segment)
加載的是可執行文件數據段,存儲于數據段(全局初始化,靜態初始化數據,文字常量(只讀))的數據的生存周期為整個程序運行過程。
棧區(stack)
棧是一種先進后出的內存結構,由編譯器自動分配釋放,存放函數的參數值、返回值、局部變量等。在程序運行過程中實時加載和釋放,因此,局部變量的生存周期為申請到釋放該段棧空間。
堆區(heap)
堆是一個大容器,它的容量要遠遠大于棧,但沒有棧那樣先進后出的順序。用于動態內存分配。堆在內存中位于BSS區和棧區之間。一般由程序員分配和釋放,若程序員不釋放,程序結束時由操作系統回收。
變量
局部變量:
概念:定義在函數內部的變量。
作用域:從定義位置開始,到包裹該變量的第一個右大括號結束。
生命周期:局部變量:從變量定義開始,函數調用完成。 --- 函數內部。
全局變量:
概念:定義在函數 外 部的變量。
作用域:從定義位置開始,默認到本文件內部。 其他文件如果想使用,可以通過聲明方式將作用域導出。
生命周期:程序啟動開始,程序終止結束。 --- 程序執行期間。
static全局變量:
定義語法: 在全局變量定義之前添加 static 關鍵字。 static int a = 10;
作用域:被限制在本文件內部,不允許通過聲明導出到其他文件。
生命周期:程序啟動開始,程序終止結束。 --- 程序執行期間。
static局部變量:
定義語法: 在局部變量定義之前添加 static 關鍵字。
特性: 靜態局部變量只定義一次。在全局位置。 通常用來做計數器。
作用域:從定義位置開始,到包裹該變量的第一個右大括號結束。
生命周期:程序啟動開始,程序終止結束。 --- 程序執行期間
全局函數: 函數
定義語法: 函數原型 + 函數體
生命周期:程序啟動開始,程序終止結束。 --- 程序執行期間。
static函數:
定義語法:static + 函數原型 + 函數體
static 函數 只能在 本文件內部使用。 其他文件即使聲明也無效。
生命周期:程序啟動開始,程序終止結束。 --- 程序執行期間。
內存4區模型
代碼段:.text段。 程序源代碼(二進制形式)。
數據段:只讀數據段 .rodata段。初始化數據段 .data段。 未初始化數據段 .bss 段。
stack:棧。 在其之上開辟 棧幀。 windows 1M --- 10M Linux: 8M --- 16M
heap:堆。 給用戶自定義數據提供空間。 約 1.3G+
當全局變量與局部變量命名沖突時采用就近原則
開辟釋放 heap 空間
void *malloc(size_t size); 申請 size 大小的空間
返回實際申請到的內存空間首地址。 【我們通常拿來當數組用】
void free(void *ptr); 釋放申請的空間
參數: malloc返回的地址值。
使用 heap 空間
空間時連續。 當成數組使用。
free后的空間,不會立即失效。 通常將free后的 地址置為NULL。
free 地址必須 是 malloc申請地址。否則出錯。
如果malloc之后的地址一定會變化,那么使用臨時變量tmp 保存。
代碼
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> int main() { //int arr[1000000] = {10, 20, 40}; int *p = (int *)malloc(sizeof(int) * 10); //char *str = (char *)malloc(sizeof(char)*10); if (p == NULL) { printf("malloc error\n"); return -1; } char *tmp = p; // 記錄malloc返回的地址值。用于free // 寫數據到 malloc 空間。 for (size_t i = 0; i < 10; i++) { p[i] = i + 10; } // 讀出malloc空間中的數據 //for (size_t i = 0; i < 10; i++) //{ // printf("%d ", *(p+i)); //} for (size_t i = 0; i < 10; i++) { printf("%d ", *p); p++; } // 釋放申請的內存。 free(tmp); p = NULL; system("pause"); return EXIT_SUCCESS; }
二級指針對應的 heap空間
申請外層指針: char **p = (char **)malloc(sizeof(char *) * 5);
申請內層指針:
for(i = 0; i < 5; i++) { p[i] = (char *)malloc(sizeof(char) *10); }
使用: 不能修改 p 的值。
for(i = 0; i < 5; i++) { strcpy(p[i], "helloheap"); }
釋放內層:
for(i = 0; i < 5; i++) { free(p[i]); }
釋放外層:
free(p);
原文鏈接:https://blog.csdn.net/qq_64691289/article/details/127694728
相關推薦
- 2022-07-13 Linux下網絡配置和ifconfig命令的使用
- 2022-04-20 從0編寫區塊鏈之用python解釋區塊鏈最基本原理_python
- 2022-08-03 C++?sort排序函數用法詳解_C 語言
- 2022-06-23 Python+Turtle制作獨特的表白圖_python
- 2023-05-31 python常用函數random()函數詳解_python
- 2022-08-18 python列表生成器常用迭代器示例詳解_python
- 2022-04-25 關于mongoDB數據庫添加賬號的問題_MongoDB
- 2022-05-25 utf8_unicode_ci和utf8_general_ci區別
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支