欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言內(nèi)存分布與heap空間分別詳細(xì)講解

 更新時(shí)間:2022年11月07日 09:18:57   作者:莫淺子  
一個(gè)程序本質(zhì)上都是由 BSS 段、data段、text段三個(gè)組成的。這種概念在當(dāng)前的計(jì)算機(jī)程序設(shè)計(jì)中是非常重要的一個(gè)基本概念,并且在嵌入式系統(tǒng)的設(shè)計(jì)中也非常重要,牽涉到嵌入式系統(tǒng)執(zhí)行時(shí)的內(nèi)存大小分配,存儲(chǔ)單元占用空間大小的問題

內(nèi)存分布

程序沒有加載到內(nèi)存前,可執(zhí)行程序內(nèi)部已經(jīng)分好3段信息,分別為代碼區(qū)(text)、數(shù)據(jù)區(qū)(data)和未初始化數(shù)據(jù)區(qū)(bss)3 個(gè)部分(有些人直接把data和bss合起來叫做靜態(tài)區(qū)或全局區(qū))。

代碼區(qū)

存放 CPU 執(zhí)行的機(jī)器指令。通常代碼區(qū)是可共享的(即另外的執(zhí)行程序可以調(diào)用它),使其可共享的目的是對(duì)于頻繁被執(zhí)行的程序,只需要在內(nèi)存中有一份代碼即可。代碼區(qū)通常是只讀的,使其只讀的原因是防止程序意外地修改了它的指令。另外,代碼區(qū)還規(guī)劃了局部變量的相關(guān)信息。

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

該區(qū)包含了在程序中明確被初始化的全局變量、已經(jīng)初始化的靜態(tài)變量(包括全局靜態(tài)變量和局部靜態(tài)變量)和常量數(shù)據(jù)(如字符串常量)。

未初始化數(shù)據(jù)區(qū)(又叫 bss 區(qū))

存入的是全局未初始化變量和未初始化靜態(tài)變量。未初始化數(shù)據(jù)區(qū)的數(shù)據(jù)在程序開始執(zhí)行之前被內(nèi)核初始化為 0 或者空(NULL)。

程序在加載到內(nèi)存前,代碼區(qū)和全局區(qū)(data和bss)的大小就是固定的,程序運(yùn)行期間不能改變。然后,運(yùn)行可執(zhí)行程序,系統(tǒng)把程序加載到內(nèi)存,除了根據(jù)可執(zhí)行程序的信息分出代碼區(qū)(text)、數(shù)據(jù)區(qū)(data)和未初始化數(shù)據(jù)區(qū)(bss)之外,還額外增加了棧區(qū)、堆區(qū)。

代碼區(qū)(text segment)

加載的是可執(zhí)行文件代碼段,所有的可執(zhí)行代碼都加載到代碼區(qū),這塊內(nèi)存是不可以在運(yùn)行期間修改的。

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

加載的是可執(zhí)行文件BSS段,位置可以分開亦可以緊靠數(shù)據(jù)段,存儲(chǔ)于數(shù)據(jù)段的數(shù)據(jù)(全局未初始化,靜態(tài)未初始化數(shù)據(jù))的生存周期為整個(gè)程序運(yùn)行過程。

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

加載的是可執(zhí)行文件數(shù)據(jù)段,存儲(chǔ)于數(shù)據(jù)段(全局初始化,靜態(tài)初始化數(shù)據(jù),文字常量(只讀))的數(shù)據(jù)的生存周期為整個(gè)程序運(yùn)行過程。

棧區(qū)(stack)

棧是一種先進(jìn)后出的內(nèi)存結(jié)構(gòu),由編譯器自動(dòng)分配釋放,存放函數(shù)的參數(shù)值、返回值、局部變量等。在程序運(yùn)行過程中實(shí)時(shí)加載和釋放,因此,局部變量的生存周期為申請(qǐng)到釋放該段??臻g。

堆區(qū)(heap)

堆是一個(gè)大容器,它的容量要遠(yuǎn)遠(yuǎn)大于棧,但沒有棧那樣先進(jìn)后出的順序。用于動(dòng)態(tài)內(nèi)存分配。堆在內(nèi)存中位于BSS區(qū)和棧區(qū)之間。一般由程序員分配和釋放,若程序員不釋放,程序結(jié)束時(shí)由操作系統(tǒng)回收。

變量

局部變量:

概念:定義在函數(shù)內(nèi)部的變量。

作用域:從定義位置開始,到包裹該變量的第一個(gè)右大括號(hào)結(jié)束。

生命周期:局部變量:從變量定義開始,函數(shù)調(diào)用完成。 --- 函數(shù)內(nèi)部。

全局變量:

概念:定義在函數(shù) 外 部的變量。

作用域:從定義位置開始,默認(rèn)到本文件內(nèi)部。 其他文件如果想使用,可以通過聲明方式將作用域?qū)С觥?/p>

生命周期:程序啟動(dòng)開始,程序終止結(jié)束。 --- 程序執(zhí)行期間。

static全局變量:

定義語法: 在全局變量定義之前添加 static 關(guān)鍵字。 static int a = 10;

作用域:被限制在本文件內(nèi)部,不允許通過聲明導(dǎo)出到其他文件。

生命周期:程序啟動(dòng)開始,程序終止結(jié)束。 --- 程序執(zhí)行期間。

static局部變量:

定義語法: 在局部變量定義之前添加 static 關(guān)鍵字。

特性: 靜態(tài)局部變量只定義一次。在全局位置。 通常用來做計(jì)數(shù)器。

作用域:從定義位置開始,到包裹該變量的第一個(gè)右大括號(hào)結(jié)束。

生命周期:程序啟動(dòng)開始,程序終止結(jié)束。 --- 程序執(zhí)行期間

全局函數(shù): 函數(shù)

定義語法: 函數(shù)原型 + 函數(shù)體

生命周期:程序啟動(dòng)開始,程序終止結(jié)束。 --- 程序執(zhí)行期間。

static函數(shù):

定義語法:static + 函數(shù)原型 + 函數(shù)體

static 函數(shù) 只能在 本文件內(nèi)部使用。 其他文件即使聲明也無效。

生命周期:程序啟動(dòng)開始,程序終止結(jié)束。 --- 程序執(zhí)行期間。

內(nèi)存4區(qū)模型

代碼段:.text段。 程序源代碼(二進(jìn)制形式)。

數(shù)據(jù)段:只讀數(shù)據(jù)段 .rodata段。初始化數(shù)據(jù)段 .data段。 未初始化數(shù)據(jù)段 .bss 段。

stack:棧。 在其之上開辟 棧幀。 windows 1M --- 10M Linux: 8M --- 16M

heap:堆。 給用戶自定義數(shù)據(jù)提供空間。 約 1.3G+

當(dāng)全局變量與局部變量命名沖突時(shí)采用就近原則

開辟釋放 heap 空間

void *malloc(size_t size); 申請(qǐng) size 大小的空間

返回實(shí)際申請(qǐng)到的內(nèi)存空間首地址。 【我們通常拿來當(dāng)數(shù)組用】

void free(void *ptr); 釋放申請(qǐng)的空間

參數(shù): malloc返回的地址值。

使用 heap 空間

空間時(shí)連續(xù)。 當(dāng)成數(shù)組使用。

free后的空間,不會(huì)立即失效。 通常將free后的 地址置為NULL。

free 地址必須 是 malloc申請(qǐng)地址。否則出錯(cuò)。

如果malloc之后的地址一定會(huì)變化,那么使用臨時(shí)變量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
	// 寫數(shù)據(jù)到 malloc 空間。
	for (size_t i = 0; i < 10; i++)
	{
		p[i] = i + 10;
	}
	// 讀出malloc空間中的數(shù)據(jù)
	//for (size_t i = 0; i < 10; i++)
	//{
	//	printf("%d ", *(p+i));
	//}
	for (size_t i = 0; i < 10; i++)
	{
		printf("%d ", *p);
		p++;
	}
	// 釋放申請(qǐng)的內(nèi)存。
	free(tmp);
	p = NULL;
	system("pause");
	return EXIT_SUCCESS;
}

二級(jí)指針對(duì)應(yīng)的 heap空間

申請(qǐng)外層指針: char **p = (char **)malloc(sizeof(char *) * 5);

申請(qǐng)內(nèi)層指針:

 for(i = 0; i < 5; i++)
 {
     p[i] = (char *)malloc(sizeof(char) *10);
 }

使用: 不能修改 p 的值。

 for(i = 0; i < 5; i++)
 {
     strcpy(p[i], "helloheap");
 }

釋放內(nèi)層:

 for(i = 0; i < 5; i++)
 {
     free(p[i]);
 }

釋放外層:

free(p);

到此這篇關(guān)于C語言內(nèi)存分布與heap空間分別詳細(xì)講解的文章就介紹到這了,更多相關(guān)C語言內(nèi)存分布與heap空間內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++?繼承的范例講解

    C++?繼承的范例講解

    繼承是C++面向?qū)ο缶幊讨械囊婚T。繼承是子類繼承父類的特征和行為,或者是繼承父類得方法,使的子類具有父類得的特性和行為。重寫是子類對(duì)父類的允許訪問的方法實(shí)行的過程進(jìn)行重新編寫,返回值和形參都不能改變。就是對(duì)原本的父類進(jìn)行重新編寫,但是外部接口不能被重寫
    2022-06-06
  • C++實(shí)現(xiàn)LeetCode(109.將有序鏈表轉(zhuǎn)為二叉搜索樹)

    C++實(shí)現(xiàn)LeetCode(109.將有序鏈表轉(zhuǎn)為二叉搜索樹)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(109.將有序鏈表轉(zhuǎn)為二叉搜索樹),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語言詳細(xì)分析宏定義與預(yù)處理命令的應(yīng)用

    C語言詳細(xì)分析宏定義與預(yù)處理命令的應(yīng)用

    宏定義是用宏名來表示一個(gè)字符串,在宏展開時(shí)又以該字符串取代宏名,這只是一種簡(jiǎn)單的替換。字符串中可以含任何字符,可以是常數(shù),也可以是表達(dá)式,預(yù)處理程序?qū)λ蛔魅魏螜z查,如有錯(cuò)誤,只能在編譯已被宏展開后的源程序時(shí)發(fā)現(xiàn)
    2022-07-07
  • C/C++實(shí)現(xiàn)貪吃蛇逐步運(yùn)動(dòng)效果

    C/C++實(shí)現(xiàn)貪吃蛇逐步運(yùn)動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了C/C++實(shí)現(xiàn)貪吃蛇逐步運(yùn)動(dòng)效果的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • C++11?lambda(匿名函數(shù))表達(dá)式詳細(xì)介紹

    C++11?lambda(匿名函數(shù))表達(dá)式詳細(xì)介紹

    lambda 表達(dá)式(lambda expression)是一個(gè)匿名函數(shù),C++11中的lambda表達(dá)式用于定義并創(chuàng)建匿名的函數(shù)對(duì)象,以簡(jiǎn)化編程工作,下面這篇文章主要給大家介紹了關(guān)于C++11?lambda(匿名函數(shù))表達(dá)式的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • Assert(斷言實(shí)現(xiàn)機(jī)制深入剖析)

    Assert(斷言實(shí)現(xiàn)機(jī)制深入剖析)

    言前后最好空一格[編程風(fēng)格的問題,按你自已的喜好,適合自已就最好]。斷言只是用來檢查程序的邏輯正確性,不能代替條件替換。斷言比printf語句這種形式的打印好使
    2013-09-09
  • C語言實(shí)現(xiàn)隨機(jī)發(fā)撲克牌

    C語言實(shí)現(xiàn)隨機(jī)發(fā)撲克牌

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)隨機(jī)發(fā)撲克牌,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • c語言中實(shí)現(xiàn)數(shù)組幾個(gè)數(shù)求次大值

    c語言中實(shí)現(xiàn)數(shù)組幾個(gè)數(shù)求次大值

    這篇文章主要介紹了c語言中實(shí)現(xiàn)數(shù)組幾個(gè)數(shù)求次大值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • C++與namespace有關(guān)的兩個(gè)編譯錯(cuò)誤的講解

    C++與namespace有關(guān)的兩個(gè)編譯錯(cuò)誤的講解

    今天小編就為大家分享一篇關(guān)于C++與namespace有關(guān)的兩個(gè)編譯錯(cuò)誤的講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • C++構(gòu)造函數(shù)初始化列表的實(shí)現(xiàn)詳解

    C++構(gòu)造函數(shù)初始化列表的實(shí)現(xiàn)詳解

    構(gòu)造函數(shù)主要作用在于創(chuàng)建對(duì)象時(shí)為對(duì)象的成員屬性賦值,構(gòu)造函數(shù)由編譯器自動(dòng)調(diào)用,無須手動(dòng)調(diào)用;析構(gòu)函數(shù)主要作用在于對(duì)象銷毀前系統(tǒng)自動(dòng)調(diào)用,執(zhí)行一 些清理工作
    2022-09-09

最新評(píng)論