国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C語言】-- 一篇帶你了解C語言內(nèi)存五大區(qū)——棧區(qū),堆區(qū),全局區(qū),常量區(qū),代碼區(qū)

這篇具有很好參考價值的文章主要介紹了【C語言】-- 一篇帶你了解C語言內(nèi)存五大區(qū)——棧區(qū),堆區(qū),全局區(qū),常量區(qū),代碼區(qū)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

1 C語言的內(nèi)存分區(qū)

1.1 內(nèi)存五大分區(qū)

1.2 內(nèi)存分區(qū)簡介

1.2.1 棧區(qū)(stack)

1.2.2 堆區(qū)(heap)

1.2.3 (全局)靜態(tài)區(qū)

1.2.4 常量區(qū)

1.2.5 代碼區(qū)

創(chuàng)作不易,如果本篇博客對您有一定的幫助,大家記得留言+點贊哦。


C語言已經(jīng)持續(xù)學(xué)習(xí)一段時間了,今天特此總結(jié)一下關(guān)于C語言內(nèi)存的五大區(qū)。它是我們深入理解C語言非常有必要了解的知識點。通過了解五大區(qū),對于進一步學(xué)習(xí)C語言底層是非常有幫助的。

1 C語言的內(nèi)存分區(qū)

1.1 內(nèi)存五大分區(qū)

C語言內(nèi)存可大致分為5個區(qū)域,圖和表如下:

內(nèi)存影像區(qū) 內(nèi)容 ?權(quán)限
棧區(qū) 函數(shù)中的普通變量 可讀可寫
堆區(qū) 動態(tài)申請的內(nèi)存 可讀可寫
(全局)靜態(tài)變量區(qū) static修飾的變量 可讀可寫
常量區(qū) 用于初始化變量的常量 只讀
代碼區(qū) 代碼指令 只讀

【C語言】-- 一篇帶你了解C語言內(nèi)存五大區(qū)——棧區(qū),堆區(qū),全局區(qū),常量區(qū),代碼區(qū),c語言,開發(fā)語言,C語言內(nèi)存五大區(qū)

nt k=1;
void main()
{
	int i=1;
	char *j;
	static int m=1;
	char *n="hello";
 
	printf("棧區(qū)地址為:0X%x\n",&i);		
	j = (char*)malloc(2); //一般不確定需要多大空間的時候用
	free(j);//及時釋放
	printf("堆區(qū)地址為:0X%x\n",j);
	printf("全局變量地址為:0X%x\n",&k);
	printf("靜態(tài)變量地址為:0X%x\n",&m);
	printf("文字常量區(qū)地址為:0X%x\n",n);
	printf("程序區(qū)地址為:0X%x\n",&main);
}
 
	char *i="hello";
	char j[10]="hello";
	printf("0X%x\n",i); //存放在文字常量區(qū)
	printf("0X%x\n",j); //存放在棧區(qū)
	j[1]='*';//可以直接賦值
	//*(i+1)='*'; //等價于i[1]='*';
	//不可以這樣賦值, 因為i是指針,指向的是文字常量區(qū),里面的內(nèi)容是不能修改的
	i=j; //這樣可以
	printf("%s\n",i);
	printf("%x\n",i);
	j=i;//這樣不可以,因為j雖然也是地址,但是不是指針變量,不能直接賦值

1.2 內(nèi)存分區(qū)簡介

1.2.1 棧區(qū)(stack)

棧區(qū)由編譯器自動分配釋放,由操作系統(tǒng)自動管理,無須手動管理。
棧區(qū)上的內(nèi)容只在函數(shù)范圍內(nèi)存在,當(dāng)函數(shù)運行結(jié)束,這些內(nèi)容也會自動被銷毀。

#include<stdio.h>
char *getMem()
{
	char buf[64]; //局部變量 棧區(qū)存放
	strcpy(buf, "123456789");//向buf所代表的內(nèi)存中寫入內(nèi)容
	//printf("buf:%s\n", buf);
	return buf;//返回所分配內(nèi)存區(qū)域的第一個元素的地址
}
 
void main()
{
	char *tmp = NULL;
	tmp = getMem(10);
	if (tmp == NULL)
	{
		return ;
	}
	printf("tmp:%s\n", tmp);//輸出tmp:
	system("pause");
	return ;
}

內(nèi)存分析:

? ? ??

?

  • 棧區(qū)按內(nèi)存地址由高到低方向生長,其最大大小由編譯時確定,速度快,但自由性差,最大空間不大。
  • 棧區(qū)是先進后出原則,即先進去的被堵在屋里的最里面,后進去的在門口,釋放的時候門口的先出去。
  • 棧區(qū)存放內(nèi)容

  • 臨時創(chuàng)建的局部變量const定義的局部變量存放在棧區(qū)。
  • 函數(shù)調(diào)用和返回時,其入口參數(shù)返回值存放在棧區(qū)。

通俗來說:

棧區(qū)是用來存放局部變量的,比如函數(shù)內(nèi)部定義的int a,int b,const int a,char p,char arr[ ],還有函數(shù)的形參等等都是存放在棧區(qū)。棧區(qū)的數(shù)據(jù)由編譯器管理,調(diào)用完之后就自動釋放,壓棧,出棧。先進后出的原則,比如當(dāng)你執(zhí)行到函數(shù)調(diào)用的時候,編譯器會先把下一條代碼的地址壓入棧中,再把你調(diào)用的那個函數(shù)里的一些局部變量啊,形參啊等等壓入棧中,等你函數(shù)調(diào)用執(zhí)行完畢。棧就會把你調(diào)用的這個函數(shù)之前壓入棧的變量和形參全部清除出棧,之后根據(jù)下一條代碼的地址,接著執(zhí)行程序,以后的程序也都是這么執(zhí)行。棧區(qū)是有大小的,一般是1M左右,所以別定義太大的數(shù)組。
?

1.2.2 堆區(qū)(heap)

堆區(qū)由程序員分配內(nèi)存和釋放。若程序員不釋放,程序結(jié)束時可能由操作系統(tǒng)回收。

#include <stdio.h>
char *getMem(int num)
{
	char *p1 = NULL;
	p1 = (char *)malloc(sizeof(char) * num);
	if (p1 == NULL)
	{
		return NULL;
	}
	return p1;
}
void main()
{
	char *tmp = NULL;
	tmp = getMem(10);
	if (tmp == NULL)
	{
		return ;
	}
	strcpy(tmp, "111222"); //向tmp做指向的內(nèi)存空間中copy數(shù)據(jù),注意不是向指針變量tmp中
	printf("tmp:%s\n", tmp);//輸出tmp:111222
	system("pause");
	return ;
}

內(nèi)存分析:

? ? ? ??

?

  • 堆區(qū)按內(nèi)存地址由低到高方向生長,其大小由系統(tǒng)內(nèi)存/虛擬內(nèi)存上限決定,速度較慢,但自由性大,可用空間大。

堆區(qū)動態(tài)申請與釋放內(nèi)存
malloc(),free()等函數(shù)實現(xiàn)動態(tài)分布內(nèi)存。

void *malloc(size_t);
  • 參數(shù)size_t是分配的字節(jié)大小;
  • 返回值是一個void*型的指針,該指針指向分配空間的首地址;
    void *型指針可以任意轉(zhuǎn)換為其他類型的指針)

free()函數(shù)進行內(nèi)存釋放,否則會造成內(nèi)存泄漏。

void free(void * /*ptr*/);
  • 參數(shù)ptr是開辟的內(nèi)存的首地址。
  • 無返回值;

通俗來說:

由程序員手動申請和釋放
比如:int?p=(int?)malloc(sizeof(int)10),表示申請了一塊40個字節(jié)的堆區(qū)空間,然后申請完記得用free釋放。
代碼區(qū)的話就是用來存放代碼的,轉(zhuǎn)化為二進制存放。

1.2.3 (全局)靜態(tài)區(qū)

通常是用于那些在編譯期間就能確定存儲大小的變量的存儲區(qū),但它用于的是在整個程序運行期間都可見的全局變量靜態(tài)變量。
全局區(qū)有?.bss段?和?.data段組成,可讀可寫。

#include <stdio.h>
char * getStr1()
{
	char *p1 = "abcd";
	return p1;
}
char *getStr2()
{
	char *p2 = "abcd";
	return p2;
}
 
void main()
{
	char *p1 = NULL;
	char *p2 = NULL;
	p1 = getStr1();
	p2 = getStr2();
 
	//打印p1 p2 所指向內(nèi)存空間的數(shù)據(jù),不是p1 p2中的數(shù)據(jù)
	printf("p1:%s , p2:%s \n", p1, p2);//輸出p1:abcd , p2:abcd
 
	//打印p1 p2 的值
	printf("p1:%d , p2:%d \n", p1, p2);//輸出p1:19184372 , p2:19184372
 
	system("pause");
	return;
}

內(nèi)存分析:

? ? ? ? ?

?

  • .bss段
    未初始化的全局變量和未初始化的靜態(tài)變量存放在.bss段。
    初始化為0的全局變量和初始化為0的靜態(tài)變量存放在.bss段。
    .bss段不占用可執(zhí)行文件空間,其內(nèi)容由操作系統(tǒng)初始化。
  • .data段
    已初始化的全局變量存放在.data段。
    已初始化的靜態(tài)變量存放在.data段。
    .data段占用可執(zhí)行文件空間,其內(nèi)容有程序初始化。

通俗來說:

全局區(qū)比較特殊,里面還分成了全局變量區(qū),靜態(tài)變量區(qū),常量區(qū)。全局變量區(qū)用來存放全局變量,靜態(tài)變量區(qū)用來存放帶有static修飾的變量(包括靜態(tài)局部變量和靜態(tài)全局變量),只要含有static就存在這個區(qū)。常量區(qū)是用來存放字符常量的,還有const修飾的全局變量的,const 修飾的局部變量不存在這里,別搞混了。全局區(qū)存放的一切都是由操作系統(tǒng)管理,等程序結(jié)束由操作系統(tǒng)釋放。常量區(qū)里存放的數(shù)據(jù)不可更改,就算你用指針也不行,你可能會說const修飾的局部變量都可以用指針改,但是局部變量可不是存放在常量區(qū),這點搞清楚。

1.2.4 常量區(qū)

字符串、數(shù)字等常量存放在常量區(qū)。
const修飾的全局變量存放在常量區(qū)。
程序運行期間,常量區(qū)的內(nèi)容不可以被修改。

1.2.5 代碼區(qū)

程序執(zhí)行代碼存放在代碼區(qū),其值不能修改(若修改則會出現(xiàn)錯誤)。
字符串常量define定義的常量也有可能存放在代碼區(qū)。

? ? ? ? 以上五區(qū),代碼區(qū)和全局區(qū)是在生成.exe文件之后就有了,雙擊.exe文件運行程序才會生成棧區(qū)和堆區(qū)。
下面直接上圖:

#include<stdio.h>
#include<string.h>
int a = 10;
static int b = 20;
void fun(int x)
{
	char *p = "Hello";
	printf("形參x的地址=%d\n\n", &x);
	printf("Hello的地址=%d\n\n", "Hello");
	printf("指針變量p的地址=%d\n\n", &p);
	return;
}
int main(int argc,const char *argv[])
{
	int c = 10;
	int d = 20;
	static int e = 30;
	char *p = "Hello";
	printf("\n全局變量a的地址=%d\n\n", &a);
	printf("靜態(tài)全局變量b的地址=%d\n\n", &b);
	printf("靜態(tài)局部變量e的地址=%d\n\n", &e);
	printf("字符串\"Hello\"的地址=%d\n\n", "Hello");
	printf("局部變量c的地址=%d\n\n", &c);
	printf("局部變量d的地址=%d\n\n", &d);
	printf("指針變量p的地址=%d\n\n", &p);
	fun(5);
	system("pause");
	return 0;
}

【C語言】-- 一篇帶你了解C語言內(nèi)存五大區(qū)——棧區(qū),堆區(qū),全局區(qū),常量區(qū),代碼區(qū),c語言,開發(fā)語言,C語言內(nèi)存五大區(qū)

【C語言】-- 一篇帶你了解C語言內(nèi)存五大區(qū)——棧區(qū),堆區(qū),全局區(qū),常量區(qū),代碼區(qū),c語言,開發(fā)語言,C語言內(nèi)存五大區(qū)

?簡單的用圖表示了一下,總結(jié):
全局區(qū)存放的是全局變量,靜態(tài)變量,字符常量,const 修飾的全局變量。棧區(qū)存放的是局部變量和函數(shù)的形參,以及一些代碼的地址,棧區(qū)的內(nèi)容是可以修改的
堆區(qū)是由程序員手動申請和釋放,用malloc函數(shù)申請,用free函數(shù)釋放。文章來源地址http://www.zghlxwxcb.cn/news/detail-602525.html

創(chuàng)作不易,如果本篇博客對您有一定的幫助,大家記得留言+點贊哦。

到了這里,關(guān)于【C語言】-- 一篇帶你了解C語言內(nèi)存五大區(qū)——棧區(qū),堆區(qū),全局區(qū),常量區(qū),代碼區(qū)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)】一篇帶你徹底了解棧

    【數(shù)據(jù)結(jié)構(gòu)】一篇帶你徹底了解棧

    棧:一種線性數(shù)據(jù)結(jié)構(gòu),其只允許在固定的一端進行插入和刪除元素操作。進行數(shù)據(jù)插入和刪除操作的一端稱為棧頂 (Top), 另一端稱為棧底 [Bottom]。棧中的數(shù)據(jù)元素遵守后進先出LIFO(Last In First Out)的原則。即最后進入的元素最先被訪問。 壓棧:棧的插入操作叫做進棧/壓棧

    2024年02月05日
    瀏覽(26)
  • [Linux 基礎(chǔ)] 一篇帶你了解linux權(quán)限問題

    [Linux 基礎(chǔ)] 一篇帶你了解linux權(quán)限問題

    Linux下有兩種用戶:超級用戶(root)、普通用戶。 超級用戶:可以再linux系統(tǒng)下做任何事情,不受限制 普通用戶:在linux下做有限的事情。 超級用戶的命令提示符是“#”,普通用戶的命令提示符是“ $ ” 命令: su [用戶名] 功能: 切換用戶。 例如,要從root用戶切換到普通用

    2024年02月08日
    瀏覽(21)
  • [ C++ ] 一篇帶你了解C++中隱藏的this指針

    [ C++ ] 一篇帶你了解C++中隱藏的this指針

    本篇文章我們將一起討論在有趣的知識點--隱藏的this指針。本篇我們要使用到之前我們所學(xué)習(xí)到的C++類與對象(1),如果有各位小伙伴還不曾了解類與對象的簡單思想,可以訪問上篇博客:[ C++ ] 帶你一篇了解什么是OOP(面向?qū)ο缶幊?,什么是封裝? -- 類與對象(上) 目錄 1.

    2024年02月07日
    瀏覽(19)
  • [數(shù)據(jù)結(jié)構(gòu) -- 手撕排序第二篇] 一篇帶你詳細(xì)了解希爾排序

    [數(shù)據(jù)結(jié)構(gòu) -- 手撕排序第二篇] 一篇帶你詳細(xì)了解希爾排序

    目錄 1、常見排序算法 1.1 插入排序基本思想 2、希爾排序 2.1 希爾排序( 縮小增量排序 ) 2.1.1 預(yù)排序階段 2.1.2 插入排序階段 2.2 單趟希爾排序 2.2.1 思路分析 2.2.2 代碼實現(xiàn) 3、希爾排序代碼實現(xiàn) 4、希爾排序時間復(fù)雜度 5、希爾排序與插入排序效率對比 6、希爾排序特性總結(jié) 直接

    2024年02月13日
    瀏覽(28)
  • [C++]類與對象(下) -- 初始化列表 -- static成員 -- 友元 -- 內(nèi)部類,一篇帶你深度了解。

    [C++]類與對象(下) -- 初始化列表 -- static成員 -- 友元 -- 內(nèi)部類,一篇帶你深度了解。

    ? 目錄 1、再談構(gòu)造函數(shù) 1.1 構(gòu)造函數(shù)體賦值 1.2 初始化列表 1.2.1 初始化列表的意義 1.3 explicit 2、static成員 2.1 問題引入 2.2 特性 3、友元 3.1 友元函數(shù) 3.2 友元類 4、內(nèi)部類 在創(chuàng)建對象時,編譯器通過調(diào)用構(gòu)造函數(shù),給對象中各個成員變量一個合適的初始值。 我們構(gòu)造函

    2024年02月12日
    瀏覽(23)
  • 數(shù)組(一篇帶你掌握數(shù)組)

    數(shù)組(一篇帶你掌握數(shù)組)

    ? ? 在之前,我們想要存儲一個數(shù)據(jù)的時候可以創(chuàng)建變量,例如存儲一個整形的變量,我們使用int類型的變量來存儲,那么如果存儲一組相同類型的數(shù)據(jù)呢?這時我們就引入了 數(shù)組 的概念。 目錄 一、一維數(shù)組的創(chuàng)建和初始化 1.1數(shù)組的創(chuàng)建 1.2 數(shù)組的初始化 1.3 一維數(shù)組的使

    2023年04月08日
    瀏覽(20)
  • 一篇帶你精通MPLS

    一篇帶你精通MPLS

    MPLS:多協(xié)議標(biāo)簽交換 可以基于多種不同的3層協(xié)議來生成2.5層的標(biāo)簽信息 包為網(wǎng)絡(luò)層的PDU,故包交換就是基于IP地址進行數(shù)據(jù)轉(zhuǎn)發(fā);也就是路由器的路由行為。(路由器和終端基于3層的IP地址數(shù)據(jù)轉(zhuǎn)發(fā)的路由行為) 原始包交換 查兩張表 在包交換過程中,數(shù)據(jù)包每經(jīng)過一個路

    2024年02月22日
    瀏覽(28)
  • Javaの一篇帶你吃透接口

    Javaの一篇帶你吃透接口

    隨著接口的到來,JavaSE的學(xué)習(xí)筆記大結(jié)局也即將來臨,最近的幾篇博客寫到了封裝,繼承,多態(tài),抽象類等等,都循序漸進得介紹了這類的知識,大家如果接口這一塊理解的很困難的話,建議去完善一下前面的知識哦 ??Java封裝 ??靜態(tài)成員 ??代碼塊 ??內(nèi)部類 ??繼承 ??多

    2023年04月08日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包