當前位置:首頁 » 編程語言 » 棧上分配c語言
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

棧上分配c語言

發布時間: 2023-02-23 02:31:23

c語言堆和棧,靜態區的理解

樓主問這樣的問題,需要澄清平台。比如windows下的與linux下的編譯器及很多嵌入式C編譯器不同。為什麼考慮嵌入式C?原因是目前C語言的很大市場在嵌入式領域。windows下,除了某些特殊需要,java,C++,C#已經優勢盡顯了。

另外,討論了半天,q在你代碼的那裡?我怎麼沒找到??我眼睛都揉紅了也沒找見呀
只好表述一下原理
VC下:
1. 函數形參和函數內部非靜態局部變數都在棧上分配(所以a,b,p本身都在棧上。但p指向的內容在堆上。q在哪裡,我找不到)。
棧的分配的方法是:sp-=字數。
sp是堆棧指針。」字數「是說:你分配一個位元組的局部變數,編譯器也給你一個字的長度的空間。原因是,堆棧是具有字長度的。16位、32位機器下,字長度為16,64位機器下,字長度為32.
而且,windows下,棧是從高地址向低地址增長的。為什麼?棧與堆共享空間,並且,堆從低向高長,棧從高向低長,降低溢出風險。

靜態區名字本身就說明了他的特性:靜止的,不隨程序的運行變化。也就是相對的說,堆和棧都是動態的。靜態區是編譯器在編譯時指定長度、鏈接時定位地址、windows載入器載入時分配內存。
這里的動與靜是編譯器和鏈接器的說法,是語言層面。不適用於系統層面。Windows隨時可能將任何用戶程序程序的全部資源「請出」內存,也可重新載入,此時,什麼靜都是浮雲。

還有返回值。樓主的main不返回值編譯器會警告你的。返回值存在什麼地方?
答案是寄存器里AX(EAX,DX,EDX等)。

嵌入式系統里可能這些都不適用。比如,某些嵌入式處理器的形參直接使用寄存器(R0~R15,或A、B等)

❷ c語言內存有幾種分配方式

基本上C程序的元素存儲在內存的時候有3種分配策略:
靜態分配
如果一個變數聲明為全局變數或者是函數的靜態變數,這個變數的存儲將使用靜態分配方式。靜態分配的內存一般會被編譯器放在數據段或代碼段來存儲,具體取決於實現。這樣做的前提是,在編譯時就必須確定變數的大小。 以IA32的x86平台及gcc編譯器為例,全局及靜態變數放在數據段的低端;全局及靜態常量放在代碼段的高端
自動分配
函數的自動局部變數應該隨著函數的返回會自動釋放(失效),這個要求在一般的體系中都是利用棧(Stack)來滿足的。相比於靜態分配,這時候,就不必絕對要求這個變數在編譯時就必須確定變數的大小,運行時才決定也不遲,但是C89仍然要求在編譯時就要確定,而C99放鬆了這個限制。但無論是C89還是C99,都不允許一個已經分配的自動變數運行時改變大小。
所以說C函數永遠不應該返回一個局部變數的地址。
要指出的是,自動分配也屬於動態分配,甚至可以用alloca函數來像分配堆(Heap)一樣進行分配,而且釋放是自動的。
動態分配
還有一種更加特殊的情況,變數的大小在運行時有可能改變,或者雖然單個變數大小不變,變數的數目卻有很大彈性,不能靜態分配或者自動分配,這時候可以使用堆(Heap)來滿足要求。ANSI C定義的堆操作函數是malloc、calloc、realloc和free。
使用堆(Heap)內存將帶來額外的開銷和風險。

❸ 關於c語言的數組

你提這個問題涉及幾個方面
1.靜態存儲區
2.靜態數組(static數組),全局數組,動態數組,局部數組
3.給數組賦初值

下面分別解答
1.靜態存儲區/BSS段/棧
一個程序一般分為3段:text段,data段,bss段
text段:就是放程序代碼的,編譯時確定,只讀,
data段:存放在編譯階段(而非運行時)就能確定的數據,可讀可寫
就是通常所說的靜態存儲區,賦了初值的全局變數和靜態變數存放在這個區域,常量也存放在這個區域
bss段:定義而沒有賦初值的全局變數和靜態變數,放在這個區域
2.數組定義
函數外不加static定義的數組為全局數組
用static定義靜態數組(函數內或函數外)
用malloc定義動態數組
函數內不加static關鍵字的數組,為局部數組
3.數組賦初值
對全局數組,定義並賦初值,則在data段,定義未賦初值,在bss段
靜態數組也一樣,無論靜態數組是在函數內還是函數外,定義並賦初值,則在data段,定義未賦初值,在bss段
動態數組,全是從堆上分配的
局部數組,從函數的棧上分配的,顯然存儲在棧上,函數結束就釋放

重點區分最具有迷惑性的以下兩種定義
int func1()
{
char s[200]="hello world!";
}

int func2()
{
static char s[200]="hello world!";
}

func1中,"hello world!"為常量數組,存放在data段
數組s從func1的棧上分配,然後常量數組的值復制到數組s中

func2中,"hello world!"為初值,數組s編譯時就確定在data段,
初值為"hello world!"

❹ 求助: C語言局部變數在棧上分配的方式是怎麼樣的

1 為什麼你覺得會覆蓋test0的內存呢?
2 一般情況下,棧是從上(高地址)往下增長的,如果你想弄明白棧的分配情況,先學會匯編,
再寫個簡單的程序,調試查看生成的匯編碼,你應該知道怎麼看吧,看完就什麼都明白了;
3 test0不會在棧上分配5個位元組,你認為會分5個位元組是不是覺得「1111」這個玩意兒佔用5個
位元組呢,這里在棧上分配的是char *變數,佔4個位元組,你可以去了解一下常量的存放問題;
4 局部變數沒有你所謂的」依次壓進棧「一說,這個詞是針對函數參數入棧說的;
5 局部變數在棧上的位置及對齊方式是編譯器說了算,一般沒人會去關心這些東西,
關心按幾個位元組對齊問題最多的還是在使用結構體的時候,序列化啊反序列化啊什麼的;
6 關於ARM,太久不用了,不敢多說;7 感覺你知道點兒東西,也想去多知道點兒,但從上面看,你基礎不扎實,有點兒亂來;

❺ c語言有幾種分配內存的方式,有什麼區別

一般而言,有兩種內存分配的方式。
1、在棧上分配。特點是當變數離開其作用域時,其內存即釋放了,例如局部變數、函數參數等都是在棧上分配的。
2、在堆上分配。特點是變數一直存在,例如new運算符分配出來的內存、全局變數和static靜態變數都是在堆上分配的。

❻ C語言問題:內存的分配方式有哪幾種

1、靜態存儲區分配

內存分配在程序編譯之前完成,且在程序的整個運行期間都存在,例如全局變數、靜態變數等。

2、棧上分配

在函數執行時,函數內的局部變數的存儲單元在棧上創建,函數執行結束時這些存儲單元自動釋放。

3、堆上分配

堆分配(又稱動態內存分配)。程序在運行時用malloc或者new申請內存,程序員自己用free或者delete釋放,動態內存的生存期由我們自己決定。

(6)棧上分配c語言擴展閱讀

棧上分配數組

#include<iostream>

usingnamespacestd;

voidmain()

{

int**arr=NULL;//int型二維數組

introws,columns;

cin>>rows;//2

cin>>columns;//3

//請在此處編寫代碼,根據rows和columns在棧上分配一個數組arr

...你的代碼...

//賦值給數組元素

for(introwIndex=0;rowIndex<rows;rowIndex++)

{

for(intcolumnIndex=0;columnIndex<columns;columnIndex++)

{

arr[rowIndex][columnIndex]=columnIndex+(rowIndex+1)*1000+1;

}

}

//列印每個數組元素

for(rowIndex=0;rowIndex<rows;rowIndex++)

{

for(intcolumnIndex=0;columnIndex<columns;columnIndex++)

{

printf("%d",arr[rowIndex][columnIndex]);

}

printf(" ");

}

}

❼ C語言可以實現為一維數組動態分配內存嗎

可以。。

例子如下:

# include <stdio.h>

# include <malloc.h>

void main(void)

{

int len,i, *p;

printf("輸入要存放元素的個數:");

scanf("%d", &len); //輸入長度構造動態一維數組

p = (int *)malloc(sizeof(int)*5);

for(i=0; i<len; ++i)

scanf("%d",(p+i)); // p+i等同於&p[i];

// 將動態一維數組p的長度增加至6,並將第6個元素賦值為100;

realloc(p,sizeof(int)*6);//realloc重新增加或減少一維數組的長度;

p[5] = 99;

printf("輸出內容: ");

for(i=0; i<=len; ++i)

printf("%-5d", p[i]); //p[i]等同於*(p+i);

printf(" ");

❽ C語言:棧中內存分配是連續的,堆中內存分配是不連續的,對嗎

1、棧中的內存是操作系統自動分配的,可以理解成為時連續的,對中的內存分配是因為我們malloc空間的時候,申請的空間的大小不一樣造成了碎片。使用malloc的時候系統內部有一個空閑內存映射表,系統會自動查找空閑內存中的第一個合適大小的空間分配。
2、每一次分配的內存是連續的,但如果用結構體鏈表來管理分配的內存就可以將每一次分配的內存虛擬的連接起來,但前提是每一次分配的內存還是連續的,只是每個節點所佔的內存單元不是連續的。

❾ C語言中全局變數存放在內存空間中那個位置

在 C 語言中,內存分配方式有以下三種形式:

1、從靜態存儲區域分配
由編譯器自動分配和釋放,在程序編譯的時候就已經分配好內存,這塊內存在程序的整個運行期間都存在,直到整個程序運行結束時才被釋放,如全局變數與 static 變數。

2、在棧上分配
同樣由編譯器自動分配和釋放,在函數執行時,函數內部的局部變數都可以在棧上創建,函數執行結束時,這些存儲單元將則被自動釋放。

需要注意的是,棧內存分配運算內置於處理器的指令集中,它的運行效率一般很高,但是分配的內存容量有限。

3、從堆上分配
也稱為動態內存分配,由程序員手動完成申請和釋放。程序在運行的時,由程序員使用內存分配函數(如 malloc 函數)來申請內存,使用完之後再由程序員自己負責使用內存釋放函數(如 free 函數)來釋放內存。

需要注意的是,如果在堆上分配了內存空間,就必須及時釋放它,否則將會導致運行的程序出現內存泄漏等錯誤。

在 C 語言中,不同類型變數的存儲位置和作用域也有所不同。

全局變數
從靜態存儲區域分配,其作用域是全局作用域,也就是整個程序的生命周期內都可以使用。如果程序是由多個源文件構成的,那麼全局變數只要在一個文件中定義,就可以在其他所有的文件中使用,但必須在其他文件中通過使用extern關鍵字來聲明該全局變數。

全局靜態變數
從靜態存儲區域分配,其生命周期也是與整個程序同在的,從程序開始到結束一直起作用。與全局變數不同的是,全局靜態變數作用域只在定義它的一個源文件內,其他源文件不能使用。

局部變數
從棧上分配,其作用域只是在局部函數內,在定義該變數的函數內,只要出了該函數,該局部變數就不再起作用,也即該變數的生命周期和該函數同在。

局部靜態變數
從靜態存儲區域分配,其在第一次初始化後就一直存在直到程序結束。該變數的特點是其作用域只在定義它的函數內可見,出了該函數就不可見了。

❿ c語言堆和棧的區別

內存分配中的堆和棧

在 C 語言中,內存分配方式不外乎有如下三種形式:

  • 從靜態存儲區域分配:它是由編譯器自動分配和釋放的,即內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在,直到整個程序運行結束時才被釋放,如全局變數與 static 變數。

  • 在棧上分配:它同樣也是由編譯器自動分配和釋放的,即在執行函數時,函數內局部變數的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元將被自動釋放。需要注意的是,棧內存分配運算內置於處理器的指令集中,它的運行效率一般很高,但是分配的內存容量有限。

  • 從堆上分配:也被稱為動態內存分配,它是由程序員手動完成申請和釋放的。即程序在運行的時候由程序員使用內存分配函數(如 malloc 函數)來申請任意多少的內存,使用完之後再由程序員自己負責使用內存釋放函數(如 free 函數)來釋放內存。也就是說,動態內存的整個生存期是由程序員自己決定的,使用非常靈活。需要注意的是,如果在堆上分配了內存空間,就必須及時釋放它,否則將會導致運行的程序出現內存泄漏等錯誤。

數據結構的堆和棧

在數據結構中,棧是一種可以實現「先進後出」(或者稱為「後進先出」)的存儲結構。假設給定棧 S=(a0,a1,…,an-1),則稱 a0為棧底,an-1為棧頂。進棧則按照 a0,a1,…,an-1的順序進行進棧;而出棧的順序則需要反過來,按照「後存放的先取,先存放的後取」的原則進行,則 an-1先退出棧,然後 an-2才能夠退出,最後再退出 a0。

在實際編程中,可以通過兩種方式來實現:使用數組的形式來實現棧,這種棧也稱為靜態棧;使用鏈表的形式來實現棧,這種棧也稱為動態棧。

相對於棧的「先進後出」特性,堆則是一種經過排序的樹形數據結構,常用來實現優先隊列等。假設有一個集合 K={k0,k1,…,kn-1},把它的所有元素按完全二叉樹的順序存放在一個數組中,並且滿足:



則稱這個集合 K 為最小堆(或者最大堆)。

由此可見,堆是一種特殊的完全二叉樹。其中,節點是從左到右填滿的,並且最後一層的樹葉都在最左邊(即如果一個節點沒有左兒子,那麼它一定沒有右兒子);每個節點的值都小於(或者都大於)其子節點的值。