c:動態分配內存空間


我講解一下c語言中動態分配內存的函數,可能有些初學c語言的人不免要問了:我們為什么要通過函數來實現動態分配內存呢?系統難道不是會自動分配內存嗎?? 既然有人會問這樣的問題,那么我在這里好好的講解一下吧! 首先讓我們熟悉一下計算機的內存吧!在計算機的系統中有四個內存區域:1)棧:在棧里面儲存一些我們定義的局部變量以及形參(形式參數);2)字符常量區:主要是儲存一些字符常量,比如:char *p_str=”cgat”;其中”cgat”就儲存在字符常量區里面;3)全局區:在全局區里儲存一些全局變量和靜態變量;4)堆:堆主要是通過動態分配的儲存空間,也就是我們接下需要講的動態分配內存空間。 什么時候我們需要動態分配內存空間呢?舉一個例子吧。int *p; 我們定義了一個指向int類型的指針p;p是用來儲存一個地址的值的,我們之所以要為p 這個變量分配空間是讓它有一個明確的指向,打個比方吧!你現在做好了一個指向方向的路標,但是你並沒有讓這個路標指向一個確切的方位,也就是說現在的這個路標是瞎指向的,這樣我們就不能夠通過它來明確到底哪里是東,哪里是西,何為北,何為南了。雖然我們在計算機的內存里定義了一個指針變量,但是我們並沒有讓這個變量指示一個確切int類型變量的地址,所以我們就必須要讓它有一個明確的指示方向。這樣我們就要通過動態分配內存的方式來認為的規定它的方向! 我們在剛剛接觸指針的時候遇到過這樣的情況,int *p;p=&a;這種方法不是指針的動態分配內存,這個叫做指針變量的初始化!初始化同樣也可以讓指針變量有方向可指。 int *p;p=malloc(n*sizeof(類型名稱));我們通過malloc()函數為一個指針變量p分配了地址,這樣我們從鍵盤上鍵入的值就這樣存儲在p里面了,接下來我們就可以對這個p進行具體的操作了,比如scanf(“%s”,p)等等。當我們對p結束操作的時候還要釋放p的內存空間。為什么要釋放內存空間呢?在上面我已經講過動態分配的變量時儲存在堆里面,但是這個堆的空間並不是無限大的,也許當我們編一個小的程序的時候可能我們並不能夠發現什么,但是對於那些大的程序,如果我們比及時釋放堆的空間的時候會放生內存泄露。所謂內存泄露是因為堆的空間北我們動態分配用完了,這樣當我們再去使用動態分配堆的空間的時候就沒有足夠的空間讓我們使用了,這樣就需要占有原來的空間,也就是會把其他的空間來儲存我們鍵入的值,這樣會導致原來儲存的數據被破壞掉,導致了內存的泄露了。 同時當我們使用malloc()函數的時候還應該注意當我們釋放完空間的時候還要將原先的指針變量賦予一個NULL,也就是賦予一個空指針,留着下次的時候使用它!如果我們不賦予|NULL行不行呢??答案是:不行的!如果我們不賦予一個空指針這樣會導致原先的指針變量成為了一個野指針!何謂野指針?野指針就是一個沒有明確指向的指針,系統不知道它會指向什么地方,野指針是很危險的,因此當我們每次使用完malloc()函數的時候都必須將指針賦予一個空指針!相對於malloc()函數,calloc()函數就不需要我們賦予NULL了,這是因為在每次調用完calloc()函數的時候系統會自動將原先的指針賦予一個空指針,即歸於“0”。calloc()函數的原型是void *calloc(count,sizeof(類型名稱));比如:p=(char*)calloc(4,sizeof(char));我們為p分配了指向char型指針的“4”個空間。 除了malloc()與calloc(),還有一個動態分配空間的函數realloc()函數,這個函數比前兩個函數分配更多的空間,原型:void *realloc(void *p,size_t size); 該函數有幾個作用: 1) 如果有足夠的空間來擴充p的內存塊,則返回一個指向p的指針; 2) 如果沒有足夠的空間來擴充p的內存塊,則為p從新分配size的空間,並把原來的內容復制給p,指向p的開頭,同時釋放原來的空間,返回一個指向新內存塊的指針; 3) 如果p=NULL,其作用於malloc()相似; 下面舉一個程序的例子: #define LONG 10 #include<string.h> #include<stdlib.h> #include<stdio.h> main() { char *message,buf[LONG]; gets(buf); message=(char*)realloc(NULL,strlen(buf)+1); strcpy(message,buf); puts(message); gets(buf); message=(char*)realloc(message,(strlen(message)+strlen(buf)+1)); strcat(message,buf); puts(message); return 0; }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM