亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解C++的靜態(tài)內(nèi)存分配與動(dòng)態(tài)內(nèi)存分配

 更新時(shí)間:2023年06月28日 09:49:45   作者:Loup&卡普  
內(nèi)存分配 (Memory Allocation) 是指為計(jì)算機(jī)程序或服務(wù)分配物理內(nèi)存空間或虛擬內(nèi)存空間的一個(gè)過(guò)程,本文主要介紹了C++的靜態(tài)內(nèi)存分配與動(dòng)態(tài)內(nèi)存分配,感興趣的同學(xué)可以參考閱讀

I - 內(nèi)存分配概述

1.1 - 定義概述

內(nèi)存分配 (Memory Allocation) 是指為計(jì)算機(jī)程序或服務(wù)分配物理內(nèi)存空間或虛擬內(nèi)存空間的一個(gè)過(guò)程。通常在程序執(zhí)行前或執(zhí)行時(shí)完成內(nèi)存分配。

1.2 - 分類概述

存在兩種類型的內(nèi)存分配:

  • 編譯時(shí)內(nèi)存分配或靜態(tài)內(nèi)存分配 (Compile-time or Static Memory Allocation)
  • 運(yùn)行時(shí)內(nèi)存分配或動(dòng)態(tài)內(nèi)存分配 (Run-time or Dynamic Memory Allocation)

靜態(tài)內(nèi)存分配

靜態(tài)內(nèi)存分配是由編譯器為聲明的變量分配內(nèi)存。內(nèi)存的地址可以通過(guò)地址操作符找到,并且可以賦值給指針變量。該內(nèi)存是在編譯時(shí)分配的。

動(dòng)態(tài)內(nèi)存分配 :

在程序執(zhí)行時(shí) (execution) 或 運(yùn)行時(shí) (run-time) 進(jìn)行的內(nèi)存分配被稱為動(dòng)態(tài)內(nèi)存分配。庫(kù)函數(shù)例如 calloc() 和 malloc() 或者操作符 new 均支持分配動(dòng)態(tài)內(nèi)存。動(dòng)態(tài)分配的內(nèi)存空間,通過(guò)這些函數(shù)或操作符的返回值分配,賦值給指針變量。

1.3 - 區(qū)別概述

序號(hào)靜態(tài)內(nèi)存分配動(dòng)態(tài)內(nèi)存分配
1在靜態(tài)內(nèi)存分配中,變量被永久地分配內(nèi)存,直到程序執(zhí)行結(jié)束/函數(shù)調(diào)用結(jié)束在動(dòng)態(tài)內(nèi)存分配中,只有當(dāng)你的程序單元被激活時(shí)才會(huì)為變量分配內(nèi)存
2靜態(tài)內(nèi)存分配在程序執(zhí)行前完成動(dòng)態(tài)內(nèi)存分配在程序執(zhí)行過(guò)程中完成
3使用棧來(lái)管理靜態(tài)分配的內(nèi)存使用堆來(lái)管理動(dòng)態(tài)分配的內(nèi)存
4較不高效 (less efficient)較高效
5在靜態(tài)內(nèi)存分配中,不存在內(nèi)存的重用在動(dòng)態(tài)內(nèi)存分配中,存在內(nèi)存的重用,而且在不需要時(shí)可以內(nèi)存可以被釋放
6在靜態(tài)內(nèi)存分配中,一旦內(nèi)存被分配,內(nèi)存大小就不能再改變在動(dòng)態(tài)內(nèi)存分配中,分配了內(nèi)存后,內(nèi)存的大小可以改變
7在靜態(tài)內(nèi)存分配方案中,我們不能重新使用未使用的內(nèi)存動(dòng)態(tài)內(nèi)存分配中,允許重復(fù)使用內(nèi)存。用戶可以在需要時(shí)分配更多的內(nèi)存。同時(shí),用戶也可以在需要時(shí)釋放內(nèi)存。
8在這種內(nèi)存分配方案中,執(zhí)行速度比動(dòng)態(tài)內(nèi)存分配要快在這種內(nèi)存分配方案中,執(zhí)行速度要比靜態(tài)內(nèi)存分配慢
9編譯時(shí)內(nèi)存分配運(yùn)行時(shí)內(nèi)存分配
10靜態(tài)分配的內(nèi)存從程序開(kāi)始保持到程序結(jié)束動(dòng)態(tài)分配的內(nèi)存可以在任意時(shí)刻釋放
11靜態(tài)的內(nèi)存分配常常用于數(shù)組等動(dòng)態(tài)的內(nèi)存分配常常用于鏈表等數(shù)據(jù)結(jié)構(gòu)

II - 靜態(tài)內(nèi)存分配

內(nèi)存必須被分配給我們所創(chuàng)建的變量,這樣實(shí)際的變量才能存在?,F(xiàn)在有一個(gè)問(wèn)題,即我們認(rèn)為它是如何運(yùn)行的,以及它實(shí)際上是如何運(yùn)行的?

計(jì)算機(jī)如何創(chuàng)建一個(gè)變量?

當(dāng)我們思考如何創(chuàng)造某樣?xùn)|西時(shí),我們會(huì)想到“從零開(kāi)始”著手干,而當(dāng)計(jì)算機(jī)創(chuàng)建一個(gè)變量 ‘X’ 時(shí),實(shí)際上情況并不是這樣;對(duì)于計(jì)算機(jī)而言,更像是一種分配,計(jì)算機(jī)只是從許多預(yù)先存在的內(nèi)存單元中分配一個(gè)內(nèi)存單元給 X。

那么什么是靜態(tài)內(nèi)存分配?當(dāng)我們聲明變量時(shí),我們實(shí)際上是在準(zhǔn)備所有會(huì)被使用的變量,這樣編譯器就知道被使用的變量實(shí)際上是用戶想要的程序的重要部分,而不是到處漂浮的流氓符號(hào)。因此,當(dāng)我們聲明變量時(shí),編譯器實(shí)際做的是將這些變量分配到它們的房間(一個(gè)內(nèi)存單元)?,F(xiàn)在,可以看出,這是在程序執(zhí)行前完成的,你不能在程序執(zhí)行時(shí)用這種方法分配變量。

示例

void func()
{
	int a;
}
int main()
{
	int b;
	int c[12];
	//...
}

上述代碼中所有的變量都是靜態(tài)分配的。

III - 動(dòng)態(tài)內(nèi)存分配

那么,既然已經(jīng)存在一種方式來(lái)完成內(nèi)存分配的工作,為什么我們需要引入另一種分配方法?為什么我們需要在程序執(zhí)行過(guò)程中分配內(nèi)存?

因?yàn)?,盡管不是很顯而易見(jiàn),但不能在運(yùn)行時(shí)分配內(nèi)存,就降低了靈活性,并與空間效率相妥協(xié)。特別是,在那些事先不知道輸入的情況下,我們會(huì)在存儲(chǔ)的低效使用和缺乏或過(guò)多的空間用來(lái)輸入數(shù)據(jù)方面受到影響(給定一個(gè)固定長(zhǎng)度的數(shù)組或類似的數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)數(shù)據(jù))。

所以引入動(dòng)態(tài)內(nèi)存分配: 在運(yùn)行時(shí),存儲(chǔ)/內(nèi)存/單元可以分配給變量的機(jī)制被稱為動(dòng)態(tài)內(nèi)存分配(不要與 DMA 相混淆)。因此,我們可以知道在運(yùn)行期間分配內(nèi)存,這使我們能夠使用我們想要的存儲(chǔ),而不用擔(dān)心任何浪費(fèi)或者不足。

為什么要使用動(dòng)態(tài)分配的原因

  • 當(dāng)我們事先不知道程序需要多少內(nèi)存的時(shí);
  • 當(dāng)我們希望數(shù)據(jù)結(jié)構(gòu)沒(méi)有固定的內(nèi)存空間上限時(shí);
  • 當(dāng)你想更有效地使用你的內(nèi)存空間時(shí)。例如: 如果你為一個(gè)一維數(shù)組分配的內(nèi)存空間是 array[20],而你最終只使用了 10 個(gè)內(nèi)存空間,那么剩下的 10 個(gè)內(nèi)存空間就被浪費(fèi)了,這些浪費(fèi)的內(nèi)存甚至不能被其他程序變量所使用;
  • 動(dòng)態(tài)創(chuàng)建的列表的插入和刪除可以非常容易地通過(guò)操作地址來(lái)完成,而在靜態(tài)分配的內(nèi)存中,插入和刪除會(huì)導(dǎo)致更多的移動(dòng)和內(nèi)存浪費(fèi);
  • 當(dāng)你想在編程中使用結(jié)構(gòu)和鏈表的概念時(shí),動(dòng)態(tài)內(nèi)存分配是必須的

C++ 代碼

int main(int argc, char* argv[])
{
	// 動(dòng)態(tài)內(nèi)存分配
	int* ptr = new int;
	int* ptr1 = new int[10];
	// 動(dòng)態(tài)分配內(nèi)存的釋放
	delete ptr;
	delete [] ptr1;
}

C 代碼

ptr = calloc(m, n);

等價(jià)于

ptr = malloc(m * n);
memset(ptr, 0, m * n);

IV - 小結(jié)

有兩種類型的可用內(nèi)存 – 棧 (stack) 和堆 (heap)。靜態(tài)內(nèi)存分配只能在棧上進(jìn)行,而動(dòng)態(tài)內(nèi)存分配可以在棧和堆上進(jìn)行。在堆上進(jìn)行動(dòng)態(tài)分配的一個(gè)例子是遞歸,在遞歸中,函數(shù)按照出現(xiàn)的順序被放入調(diào)用堆,并在到達(dá)基數(shù)時(shí)一個(gè)一個(gè)地彈出。

當(dāng)在堆上分配內(nèi)存時(shí),我們需要手動(dòng)刪除內(nèi)存,因?yàn)榧词狗峙涞膬?nèi)存范圍結(jié)束(如棧的情況),內(nèi)存也不會(huì)被編譯器自己釋放(取消分配 deallocate)。

4.1 - 靜態(tài)分配的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 使用簡(jiǎn)單
  • 分配和取消分配都由編譯器完成
  • 高效的執(zhí)行時(shí)間
  • 它使用棧數(shù)據(jù)結(jié)構(gòu)

缺點(diǎn)

  • 內(nèi)存浪費(fèi)問(wèn)題
  • 必須知道確切的內(nèi)存需求
  • 一旦初始化后,內(nèi)存的大小不能調(diào)整

4.2 - 動(dòng)態(tài)分配的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 動(dòng)態(tài)分配是在運(yùn)行時(shí)進(jìn)行的
  • 只要我們需要,我們就可以分配(創(chuàng)建)額外的存儲(chǔ)
  • 只要我們使用結(jié)束了,內(nèi)存就可以被取消分配(free / delete)動(dòng)態(tài)空間
  • 因此,人們總是可以準(zhǔn)確地?fù)碛兴璧目臻g量–不多也不少。
  • 如果需要,內(nèi)存大小可以重新分配 

缺點(diǎn)

  • 由于內(nèi)存是在運(yùn)行時(shí)分配的,因此需要更多的時(shí)間。
  • 當(dāng)完成后,內(nèi)存需要由用戶釋放。這一點(diǎn)很重要,因?yàn)樗锌赡茏兂呻y以發(fā)現(xiàn)的 bug。

總上所述,靜態(tài)內(nèi)存是編譯器提前分配的東西。而動(dòng)態(tài)內(nèi)存是在執(zhí)行過(guò)程中由程序控制的東西。程序可以要求更多的內(nèi)存,也可以刪除部分分配的內(nèi)存。

到此這篇關(guān)于詳解C++的靜態(tài)內(nèi)存分配與動(dòng)態(tài)內(nèi)存分配的文章就介紹到這了,更多相關(guān)C++ 內(nèi)存分配內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c語(yǔ)言操作文本的基本使用方法

    c語(yǔ)言操作文本的基本使用方法

    這篇文章主要介紹了c語(yǔ)言操作文本的基本使用方法,需要的朋友可以參考下
    2014-04-04
  • 關(guān)于C++面向?qū)ο笤O(shè)計(jì)的訪問(wèn)性問(wèn)題詳解

    關(guān)于C++面向?qū)ο笤O(shè)計(jì)的訪問(wèn)性問(wèn)題詳解

    這篇文章主要給大家介紹了關(guān)于C++面向?qū)ο笤O(shè)計(jì)的訪問(wèn)性問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • C++11 thread多線程編程創(chuàng)建方式

    C++11 thread多線程編程創(chuàng)建方式

    這篇文章主要介紹了C++11 thread多線程編程的相關(guān)知識(shí),包括線程的創(chuàng)建方式結(jié)束方式及互斥鎖的實(shí)例代碼詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • 如何使用C語(yǔ)言實(shí)現(xiàn)細(xì)菌的繁殖與擴(kuò)散

    如何使用C語(yǔ)言實(shí)現(xiàn)細(xì)菌的繁殖與擴(kuò)散

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)細(xì)菌的繁殖與擴(kuò)散,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C++實(shí)現(xiàn)LeetCode(2.兩個(gè)數(shù)字相加)

    C++實(shí)現(xiàn)LeetCode(2.兩個(gè)數(shù)字相加)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(兩個(gè)數(shù)字相加),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語(yǔ)言靜態(tài)鏈表和動(dòng)態(tài)鏈表

    C語(yǔ)言靜態(tài)鏈表和動(dòng)態(tài)鏈表

    靜態(tài)鏈表和動(dòng)態(tài)鏈表是線性表鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)的兩種不同的表示方式。靜態(tài)鏈表的初始長(zhǎng)度一般是固定的,在做插入和刪除操作時(shí)不需要移動(dòng)元素,僅需修改指針。動(dòng)態(tài)鏈表是相對(duì)于靜態(tài)鏈表而言的,一般地,在描述線性表的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)時(shí)如果沒(méi)有特別說(shuō)明即默認(rèn)描述的是動(dòng)態(tài)鏈表。
    2016-05-05
  • C語(yǔ)言銀行系統(tǒng)課程設(shè)計(jì)

    C語(yǔ)言銀行系統(tǒng)課程設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言銀行系統(tǒng)課程設(shè)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++判斷主機(jī)是否處于聯(lián)網(wǎng)狀態(tài)

    C++判斷主機(jī)是否處于聯(lián)網(wǎng)狀態(tài)

    這篇文章主要為大家詳細(xì)介紹了C++判斷主機(jī)是否處于聯(lián)網(wǎng)狀態(tài),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • 詳解C/C++如何發(fā)送與接收Kafka消息

    詳解C/C++如何發(fā)送與接收Kafka消息

    系統(tǒng)之間通信方式很多如:系統(tǒng)之間調(diào)用(http/rpc等),異步間接調(diào)用如發(fā)送消息、公共存儲(chǔ)等,算法工程為C/C++工程,本文將介紹如何在C/C++中如何發(fā)送與接收Kakfa消息(包含:Kafka的SASL認(rèn)證方式),并提供了詳細(xì)的源碼和講解,需要的朋友可以參考下
    2024-07-07
  • C語(yǔ)言編寫(xiě)五子棋游戲

    C語(yǔ)言編寫(xiě)五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言編寫(xiě)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02

最新評(píng)論