求程式的記憶體分配(C語言,Win32平臺儘量底層)

2022-11-01 14:10:20 字數 3455 閱讀 9738

1樓:雨愁軒

windows nt在記憶體和地址空間之間作出了區分。每個程序分配到2 gb的使用者地址空間,而不管對於該程序的實際可用實體記憶體有多少。而且,所有程序都使用相同範圍的線性32位地址,範圍從0000000016-7fffffff16,而不考慮可用記憶體的地址。

windows nt負責在適當的時間把記憶體頁對映(paging)到磁碟以及從磁碟頁對映回記憶體,使得每個程序都確保能夠定址到它所需要的記憶體。儘管有可能出現兩個程序試圖同時訪問同一虛擬地址上的記憶體,但是,實際上windows nt虛擬記憶體管理程式是在不同的物理位置描述這兩個記憶體的位置。而且這兩個地址都不見得與原始的虛擬地址一致。

這就是虛擬記憶體。

因為虛擬記憶體的存在,一個應用程式能夠管理它自己的地址空間,而不必考慮在系統中對於其它程序的影響。在windows nt中的記憶體管理程式負責檢視在任何給定的時間裡,所有的應用程式是否有足夠的實體記憶體進行有效的操作。與在windows 3.

1版本或更早的版本中不同,windows nt作業系統下的應用程式不必考慮和其它應用程式共享系統記憶體這個問題。並且,即使在應用程式自己的地址空間內,它們仍能夠與其它的應用程式共享記憶體。

區分記憶體和地址空間的一個好處是,為應用程式提供了將非常大的檔案載入到記憶體的能力。不必將一個大的檔案讀進記憶體中,windows nt為應用程式保留該檔案所需的地址範圍提供了支援。然後,在需要的時候,該檔案部分就可以被瀏覽了(物理性地讀進記憶體)。

通過虛擬記憶體的支援,對於大段的動態記憶體的分配同樣可以做到這一點。

在windows的早期版本中,在一個應用程式能夠操作記憶體中的地址之前,該應用程式必須首先分配記憶體。在windows nt中,每一個程序的地址空間已經分配好了,是否有記憶體與該段地址空間中的地址相關聯是另外的問題。win32虛擬記憶體管理函式為分別管理程序的地址和記憶體提供了低階別的支援。

win32虛擬記憶體函式的全體是:

virtualalloc 和 virtualfree

virtuallock 和 virtualunlock

virtualquery 或 virtualqueryex

virtualprotect 或 virtualprotectex

對於每個函式,如有與之相對應的,則它們共同組成一組。分配記憶體請使用virtualalloc,一旦已經分配,則必須使用virtualfree來釋放。類似地,對於被使用virtuallock鎖定的頁,當不再需要時,則必須用virtualunlock來解除鎖定。

virtualquery和virtualprotect沒有與之相對應的函式,但它們倆都有完整功能(complementary)的函式(在函式名字上的ex擴充套件來指示)。這樣,就允許它們在除呼叫程序之外的其他程序中使用,但是,此時呼叫程序需要有適當的特權才可以這樣。這些函式將在下面的適當的上下文中解釋。

2樓:

是vc++吧,

1.用new在堆上分配任意大的記憶體,用delete釋放2.可以申請棧上的記憶體,不過容量只有預設1mb3.申請靜態記憶體,用static方式,記憶體可以分配很大

c語言怎麼寫底層.這是什麼情況?

3樓:匿名使用者

????能說清一點嗎?

4樓:匿名使用者

不知道你說的什麼情況,底層?-》驅動?核心?

c語言各種資料在記憶體中的分配方式,分別對程式的執行效率有哪些影響? 5

5樓:匿名使用者

記憶體分配?

堆疊的綜合效率最高(除暫存器外),一般函式(包括main())的變數都是在堆疊內的。

你可以顯示宣告register 但是是存在暫存器還是一般的堆疊完全由編譯器決定優化,其實你加了也沒用。。。。。堆疊是在記憶體的一塊固定大小的區域,比較小,資料量大了會爆棧(綜合最高是因為會有部分內容進入暫存器,暫存器比記憶體快)。

全域性變數是在全域性變數區的,全域性變數區是在記憶體中的固定大小的一塊區域。全域性變數區也不怎麼大,但是比堆疊大多了。。。。

函式**區。。。是在記憶體 你無視好了。。。

堆區 是在記憶體的一塊很大很大的區域,一切動態建立的物件(c用alloc家族函式 c++的new)都是在堆區,一般堆區是不會爆的,除非真的很大大大大大。。

效率上講 暫存器最快,然後就是記憶體了,磁碟的讀寫不考慮。

綜上,編譯器會幫你優化的,你只要關心會不會爆棧,會不會爆全域性變數,就行了。。

還有字串常量區,也是在記憶體中的,你也無視好了。。。。。

還有靜態區也是在記憶體中的,大小是編譯器編譯時決定的,你也無視好了。。。。

6樓:

從另一個角度,從變數值存在的作時間(即生存期)角度來分,可以分為靜態儲存方式

和動態儲存方式。

靜態儲存方式:是指在程式執行期間分配固定的儲存空間的方式。

動態儲存方式:是在程式執行期間根據需要進行動態的分配儲存空間的方式。

c語言中有無堆的概念?

7樓:鷹弈

棧,堆,靜態區,是記憶體開闢的三個專屬區,c語言的記憶體分配也就只有這三種方式

1.記憶體在棧上建立(棧結構)

如函式裡定義的變數int i; char str[80],還有儲存函式的所有資訊的記憶體都是在棧上建立的

這塊記憶體是連續的,就好比是一個陣列,所以你在記憶體分配的時候,會發現變數地址是連續的

2.記憶體在堆上建立(連結串列結構)

這塊記憶體是有很多記憶體塊組成,很像鞭炮一樣串在一根繩子上,但這些記憶體塊的大小不一樣,儲存在連結串列結構中的結點中,當你用malloc動態申請是,編譯器會根據你記憶體塊的大小從表頭一次檢索,直到連結串列中的記憶體塊大於等於你所申請的記憶體大小時,返回該快記憶體,如果連結串列上的記憶體塊大於你所申請的記憶體時,會將多餘記憶體**到連結串列結構,這也就是為什麼動態申請記憶體容易造成記憶體碎片的產生原因。所以分配記憶體時你會發現他們的地址不連續

3記憶體在靜態區建立

如全域性變數,static變數

這塊記憶體也是連續的,也像一個陣列,但它跟棧上建立記憶體唯一的區別是,記憶體作用時間不一樣,靜區記憶體作用時間是整個“程式”執行時間,棧上記憶體作用時間是整個“函式”的執行時間,注意“程式”和“函式”的區別

而堆記憶體作用時間範圍是0到整個“程式”執行時間,如果你要在小於整個“程式”執行時間內釋放這塊記憶體的話,就要使用free,所以是手動申請手動釋放,你自己可以控制,但是寫**的好習慣習慣是程式中有幾個malloc就有幾個free,這樣可以防止記憶體洩露

**段指的是**段暫存器,你寫的**存放在這個暫存器裡,等待cpu呼叫,這個屬於微機原理所討論問題,有興趣可以學學

一個c程式執行系統允許最大分配記憶體是多少

8樓:du基咪

一個函式有一個最大的記憶體空間限制 大概是int的10000 記憶體空間和程式本身定義的變數有關 帶遞迴的程式記憶體空間是 本身定義的變數*遞迴層數 遞迴層數(就是從搜尋樹的高度)

9樓:叼著奶嘴成長

最大一般是剩餘可用空間的30%~40%

C語言,記憶體管理問題,C語言問題 記憶體的分配方式有哪幾種?

一樣大。name是char指標型別,它只記錄地址,不記錄地址裡面存的東西所以不管存多少東西,地址的長度是不會變的。這個sizeof struct mm的長度目測是8 在32位程式裡 變數定義之後,就會給變數分配空間了,不管你有沒有給它賦值。32位系統下,sizeof struct mm 為8位元組,...

求C語言問題的程式,求一個C語言問題的程式!

include stdio.h include string.h include ctype.h int invertion char ch1,char ch2,int n 原字串由形參傳給ch1,倒排後字串 目前是空串 傳給ch2,字串長度傳給n main 啊,看錯了,是單詞倒排不是整串倒排,你把...

求一道C語言程式答案,求一道C語言程式題的答案與解題過程

16 g 17 j 18 f 19 b 20 c 7 2x 1 3 4x 1 4 3x 2 1 5y 1 1 y 9y 1 1 3y 20 1 20 320 x 320 40 2 x 2 2 x 1 2 x 2 3 4x 1 9 1 x x 3 5 5 x 2 2 x 1 3 5 x 1 6 1 1...