日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > > 充電吧
[導(dǎo)讀]最近很多同學(xué)希望了解C語(yǔ)言的內(nèi)存分配,雖然可以在互聯(lián)網(wǎng)上找到諸多的講解,但是你會(huì)發(fā)現(xiàn)要么不通俗易懂,要么不算太全面。而這些對(duì)于新手而言,又絕對(duì)會(huì)把你弄得暈頭轉(zhuǎn)向的,所以在此對(duì)網(wǎng)上和書(shū)本上的諸般講解,進(jìn)


最近很多同學(xué)希望了解C語(yǔ)言的內(nèi)存分配,雖然可以在互聯(lián)網(wǎng)上找到諸多的講解,但是你會(huì)發(fā)現(xiàn)要么不通俗易懂,要么不算太全面。而這些對(duì)于新手而言,又絕對(duì)會(huì)把你弄得暈頭轉(zhuǎn)向的,所以在此對(duì)網(wǎng)上和書(shū)本上的諸般講解,進(jìn)行了通俗的翻譯和總結(jié)。

在說(shuō)內(nèi)存分配之前,先提一點(diǎn)題外話,因?yàn)樵诤屯瑢W(xué)們講解內(nèi)存分配的時(shí)候,他們不是很明白為什么要進(jìn)行這樣的分配。所以先講解下,計(jì)算機(jī)的組成和基本原理。

一、計(jì)算機(jī)的組成

計(jì)算機(jī)的五大組成部分:運(yùn)算器、控制器、存儲(chǔ)器、輸入設(shè)備和輸出設(shè)備。

我們都知道計(jì)算機(jī)的處理中心是CPU,它主要由運(yùn)算器和控制器組成。

1) 運(yùn)算器

實(shí)現(xiàn)算術(shù)運(yùn)算和邏輯運(yùn)算的部分,主要對(duì)數(shù)據(jù)進(jìn)行加工處理。

2) 控制器

計(jì)算機(jī)的指揮中心,它通過(guò)地址訪問(wèn)存儲(chǔ)器,從存儲(chǔ)器中取出指令(程序),并指出下一指令在存儲(chǔ)器中的位置,將取出的指令經(jīng)指令寄存器送往指令譯碼器,經(jīng)過(guò)對(duì)指令的分析產(chǎn)生相應(yīng)的操作,控制其他部件的有條不紊的工作。

執(zhí)行指令有四個(gè)步驟:取指令、指令譯碼、按指令操作碼執(zhí)行、形成下一條指令地址。

3)存儲(chǔ)器

計(jì)算機(jī)存放所有數(shù)據(jù)和程序的記憶部分,它分為兩大類(lèi):一類(lèi)是內(nèi)部存儲(chǔ)器(內(nèi)存),一類(lèi)是外部存儲(chǔ)器(外存)。存儲(chǔ)器由若干個(gè)存儲(chǔ)單元組成,每個(gè)存儲(chǔ)單元都有一個(gè)地址,計(jì)算機(jī)通過(guò)地址對(duì)存儲(chǔ)單元進(jìn)行讀寫(xiě)。

4) 輸入設(shè)備

向計(jì)算機(jī)輸入信息(程序、數(shù)據(jù)、聲音、文字、圖形、圖像等)的設(shè)備(鍵盤(pán)、鼠標(biāo)、圖形掃描儀、觸摸屏、條形碼輸入器、光筆等)。

5) 輸出設(shè)備

主要有顯示器、打印機(jī)和繪圖儀等。

二、內(nèi)存分配

在任何程序設(shè)計(jì)環(huán)境及語(yǔ)言中,內(nèi)存管理都十分重要。在目前的計(jì)算機(jī)系統(tǒng)或嵌入式系統(tǒng)中,內(nèi)存資源仍然是有限的。因此在程序設(shè)計(jì)中,有效地管理內(nèi)存資源是程序員首先考慮的問(wèn)題

1) C程序結(jié)構(gòu):可執(zhí)行代碼存儲(chǔ)時(shí)

下面是C語(yǔ)言可執(zhí)行程序的基本情況:



上面分別是:代碼區(qū)、全局初始化數(shù)據(jù)區(qū)/靜態(tài)數(shù)據(jù)區(qū)、未初始化數(shù)據(jù)區(qū)、十進(jìn)制總和、十六進(jìn)制總和、文件名。

我們可以看出程序在未運(yùn)行前,沒(méi)有調(diào)入到內(nèi)存時(shí),分為三個(gè)部分:代碼區(qū)(text)、數(shù)據(jù)區(qū)(data)、未初始化數(shù)據(jù)區(qū)(bss)。

(1) 代碼區(qū)(text)

存放CPU可執(zhí)行的機(jī)器指令,由于程序被經(jīng)常使用,防止其被意外修改,代碼區(qū)通常是只讀的。

(2) 全局初始化數(shù)據(jù)區(qū)/靜態(tài)數(shù)據(jù)區(qū)(data)

存放被初始化的全局變量、靜態(tài)變量(全局靜態(tài)變量和局部靜態(tài)變量)、常量數(shù)據(jù)(如字符串常量)。

(3) 未初始化數(shù)據(jù)區(qū)(BSS)

存放未初始化的全局變量,BSS這個(gè)叫法是根據(jù)早期的匯編運(yùn)算符而來(lái)的,這個(gè)匯編運(yùn)算符標(biāo)志著一個(gè)塊的開(kāi)始。BSS區(qū)的數(shù)據(jù)在程序開(kāi)始執(zhí)行之前被內(nèi)核初始化為0或空指針(NULL)。

2)C程序結(jié)構(gòu):程序執(zhí)行時(shí)

一個(gè)正在運(yùn)行的C程序,占用的內(nèi)存分為5個(gè)區(qū)域:代碼區(qū)、初始化數(shù)據(jù)區(qū)/靜態(tài)數(shù)據(jù)區(qū)、未初始化數(shù)據(jù)區(qū)、堆區(qū)、棧區(qū)。

(1) 代碼區(qū)(text)

代碼區(qū)指令根據(jù)程序設(shè)計(jì)流程依次執(zhí)行,對(duì)于順序指令,則只會(huì)執(zhí)行一次,如果反復(fù),則需使用跳轉(zhuǎn)指令,如果進(jìn)行遞歸,則需借助棧來(lái)實(shí)現(xiàn)。

代碼區(qū)包括操作碼和要操作的對(duì)象(或?qū)ο蟮牡刂芬?,如果是立即數(shù)(即具體的數(shù)值,如2),將直接包含在代碼中;如果是局部數(shù)據(jù),將在棧中分配空間,然后引用該數(shù)據(jù)的地址;如果是BSS區(qū)和數(shù)據(jù)區(qū),在代碼中同樣引用該數(shù)據(jù)的地址。

(2) 全局初始化數(shù)據(jù)區(qū)/靜態(tài)數(shù)據(jù)區(qū)(data)

只初始化一次。上面已經(jīng)說(shuō)過(guò),在程序編譯時(shí),該區(qū)域已經(jīng)被分配好了,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在,當(dāng)程序結(jié)束時(shí),才會(huì)被釋放。

(3)未初始化數(shù)據(jù) 區(qū)(BSS)

在運(yùn)行時(shí)改變其值。

(4)棧區(qū)(stack)

存放函數(shù)的參數(shù)值和局部變量,由編譯器自動(dòng)分配釋放,其操作方式類(lèi)似于數(shù)據(jù)結(jié)構(gòu)的棧。其特點(diǎn)是不需要程序員去考慮內(nèi)存管理的問(wèn)題,很方便;同時(shí)棧的容量很有限,在Linux系統(tǒng)中,棧的容量只有8M,并且當(dāng)相應(yīng)的范圍結(jié)束時(shí)(如函數(shù)),局部變量就不能再使用。

(5)堆區(qū)(heap)

有些操作對(duì)象只有在程序運(yùn)行時(shí)才能確定,這樣編譯器在編譯時(shí)就無(wú)法為他們預(yù)先分配空間,只有程序運(yùn)行時(shí)才分配,這就是動(dòng)態(tài)內(nèi)存分配。堆區(qū)就是用于動(dòng)態(tài)內(nèi)存分配(如malloc的動(dòng)態(tài)內(nèi)存分配),堆在內(nèi)存中位于bss區(qū)和棧區(qū)之間,一般由程序員申請(qǐng)和釋放。

之所以分配如此多的區(qū)域,主要是因?yàn)椋?/p>

一個(gè)進(jìn)程在運(yùn)行時(shí),代碼是根據(jù)流程依次執(zhí)行的,代碼只需訪問(wèn)一次,當(dāng)然跳轉(zhuǎn)或遞歸時(shí)代碼會(huì)被執(zhí)行多次,而數(shù)據(jù)一般都需要訪問(wèn)多次,因此單獨(dú)開(kāi)辟空間以便訪問(wèn)和節(jié)約空間。

下面是一個(gè)詳細(xì)的代碼,來(lái)全面分析內(nèi)存分配情況:

//main.c

int a = 0; //a在全局初始化數(shù)據(jù)區(qū)

char *p1; //p1在bss區(qū)(未初始化全局變量)

static int c = 0; //c在全局初始化數(shù)據(jù)區(qū)(c是全局靜態(tài)變量)

struct employee

{

char name[20];

int age;

float score;

}e1; //e1在全局初始化數(shù)據(jù)區(qū)

int main()

{

int b; //b在棧區(qū)(局部變量)

char s[] = “abc”; //s在棧區(qū),“abc”在常量區(qū)(全局初始化數(shù)據(jù)區(qū))

char *p2; //p2在棧區(qū)

char *p3 = “123456”; //p3在棧區(qū),“123456”在常量區(qū)(全局初始化數(shù)據(jù)區(qū))

static int d = 0; //d在全局初始化數(shù)據(jù)區(qū)(靜態(tài)局部變量)

struct student

{

char *name; //name在棧區(qū),name指針指向是在堆區(qū)

int age;

float score;

}s1; //s1在棧區(qū)

p1 = (char*)malloc(10); //分配得來(lái)的10個(gè)字節(jié)的區(qū)域在堆區(qū)

p2 = (char*)malloc(20); //分配得來(lái)的20個(gè)字節(jié)的區(qū)域在堆區(qū)

name = (cahr *)malloc(20); //分配得來(lái)的20個(gè)字節(jié)的區(qū)域在堆區(qū)

/*從常量區(qū)的“Hello World”字符串復(fù)制到剛分配到的堆區(qū)*/

strcpy(p1, “Hello World”);

free(p1); //釋放內(nèi)存

free(p2); //釋放內(nèi)存

}


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

鏈表作為一種基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),在程序設(shè)計(jì)中扮演著重要角色。掌握鏈表的高效操作技巧,特別是逆序、合并和循環(huán)檢測(cè),對(duì)于提升算法性能和解決復(fù)雜問(wèn)題至關(guān)重要。本文將詳細(xì)介紹這些操作的C語(yǔ)言實(shí)現(xiàn),并分析其時(shí)間復(fù)雜度。

關(guān)鍵字: 鏈表 C語(yǔ)言

在C/C++多文件編程中,靜態(tài)變量(static)與全局變量的作用域規(guī)則看似簡(jiǎn)單,實(shí)則暗藏諸多陷阱。開(kāi)發(fā)者若未能準(zhǔn)確理解其鏈接屬性與生命周期,極易引發(fā)難以調(diào)試的內(nèi)存錯(cuò)誤、競(jìng)態(tài)條件以及維護(hù)災(zāi)難。本文將深入剖析這兩類(lèi)變量的作...

關(guān)鍵字: 靜態(tài)變量 全局變量 C語(yǔ)言

在嵌入式系統(tǒng)和服務(wù)器開(kāi)發(fā)中,日志系統(tǒng)是故障排查和運(yùn)行監(jiān)控的核心組件。本文基于Linux環(huán)境實(shí)現(xiàn)一個(gè)輕量級(jí)C語(yǔ)言日志庫(kù),支持DEBUG/INFO/WARN/ERROR四級(jí)日志分級(jí),并實(shí)現(xiàn)按大小滾動(dòng)的文件輪轉(zhuǎn)機(jī)制。該設(shè)計(jì)在某...

關(guān)鍵字: C語(yǔ)言 嵌入式系統(tǒng)

在嵌入式系統(tǒng)和底層驅(qū)動(dòng)開(kāi)發(fā)中,C語(yǔ)言因其高效性和可控性成為主流選擇,但缺乏原生單元測(cè)試支持成為開(kāi)發(fā)痛點(diǎn)。本文提出一種基于宏定義和測(cè)試用例管理的輕量級(jí)單元測(cè)試框架方案,通過(guò)自定義斷言宏和測(cè)試注冊(cè)機(jī)制,實(shí)現(xiàn)無(wú)需外部依賴(lài)的嵌入...

關(guān)鍵字: C語(yǔ)言 嵌入式系統(tǒng) 驅(qū)動(dòng)開(kāi)發(fā)

在嵌入式系統(tǒng)開(kāi)發(fā)中,實(shí)時(shí)操作系統(tǒng)(RTOS)的任務(wù)調(diào)度算法直接影響系統(tǒng)的響應(yīng)速度和資源利用率。時(shí)間片輪轉(zhuǎn)(Round-Robin, RR)作為一種經(jīng)典的公平調(diào)度算法,通過(guò)為每個(gè)任務(wù)分配固定時(shí)間片實(shí)現(xiàn)多任務(wù)并發(fā)執(zhí)行。本文將...

關(guān)鍵字: 實(shí)時(shí)操作系統(tǒng) RTOS C語(yǔ)言

在Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)中,等待隊(duì)列(Wait Queue)是實(shí)現(xiàn)進(jìn)程睡眠與喚醒的核心機(jī)制,它允許進(jìn)程在資源不可用時(shí)主動(dòng)放棄CPU,進(jìn)入可中斷睡眠狀態(tài),待資源就緒后再被喚醒。本文通過(guò)C語(yǔ)言模型解析等待隊(duì)列的實(shí)現(xiàn)原理,結(jié)合...

關(guān)鍵字: 驅(qū)動(dòng)開(kāi)發(fā) C語(yǔ)言 Linux

在嵌入式系統(tǒng)開(kāi)發(fā)中,C語(yǔ)言與匯編的混合編程是優(yōu)化性能、訪問(wèn)特殊指令或硬件寄存器的關(guān)鍵技術(shù)。然而,內(nèi)聯(lián)匯編的語(yǔ)法差異和寄存器使用規(guī)則常導(dǎo)致難以調(diào)試的問(wèn)題。本文以ARM Cortex-M和x86架構(gòu)為例,系統(tǒng)梳理內(nèi)聯(lián)匯編的核...

關(guān)鍵字: C語(yǔ)言 匯編混合編程

在計(jì)算機(jī)安全領(lǐng)域,緩沖區(qū)溢出攻擊長(zhǎng)期占據(jù)漏洞利用榜首。這種攻擊通過(guò)向程序緩沖區(qū)寫(xiě)入超出其容量的數(shù)據(jù),覆蓋相鄰內(nèi)存區(qū)域(如返回地址),進(jìn)而實(shí)現(xiàn)任意代碼執(zhí)行。本文將深入探討棧保護(hù)機(jī)制與安全函數(shù)(如snprintf)的集成防御...

關(guān)鍵字: 棧保護(hù) 安全函數(shù) C語(yǔ)言

在嵌入式系統(tǒng)和大規(guī)模數(shù)值計(jì)算等性能敏感場(chǎng)景中,程序優(yōu)化是提升效率的關(guān)鍵環(huán)節(jié)。gprof作為GNU工具鏈中的性能分析工具,能夠精準(zhǔn)定位CPU時(shí)間消耗熱點(diǎn)。本文通過(guò)實(shí)際案例演示gprof的三個(gè)核心使用步驟,幫助開(kāi)發(fā)者快速識(shí)別...

關(guān)鍵字: C語(yǔ)言 gprof 熱點(diǎn)函數(shù)

哈希表作為高效數(shù)據(jù)檢索的核心結(jié)構(gòu),其性能高度依賴(lài)沖突解決策略。本文通過(guò)C語(yǔ)言實(shí)現(xiàn)對(duì)比鏈地址法與開(kāi)放尋址法,揭示兩種方法在內(nèi)存占用、查詢(xún)效率及實(shí)現(xiàn)復(fù)雜度上的差異,為工程實(shí)踐提供量化參考。

關(guān)鍵字: 哈希表 鏈地址法 開(kāi)放尋址法 C語(yǔ)言
關(guān)閉