C语言—静态存储与动态存储
靜態存儲和動態存儲
變量從變量值存在的時間(即生存期)角度分:靜態存儲方式和動態存儲方式
靜態:在編譯時確定了固定的內存地址與內存大小,如:函數里的局部變量、全局變量等
動態:由程序控制,運行時主動性的向系統申請所需大小的內存段,并且每次分配到的內存地址不固定
在動態存儲區存放數據:
1、函數形式參數
2、自動變量(未加static聲明)
3、函數調用時的現場保護和
返回地址
存儲類別
內存中的存儲區域包括下面幾個部分:
①程序代碼區:存放函數體的二進制代碼
②靜態區/全局區(static):全局變量和靜態變量的存儲 區域
③堆區(heap):程序員分配釋放
④棧區(stack):由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值
函數
malloc()函數
功能說明:malloc() 是最常用的函數之一,它允許從空閑內存池中分配內存
函數原型: void *malloc(size_t bytes)
bytes:要申請的字節數
返回值:成功時返回內存段首地址,否則返回NULL
注意:通過malloc函數申請的內存空間,未自動初始化
代碼示例:
#include <stdio.h> #include <windows.h> void main(){int *p,n,i,j,temp;printf("\n Enter number of elements in the array: ");scanf("%d",&n);p=(int*)malloc(n*sizeof(int));if(p == NULL){printf("memory error");return;}for(i = 0;i < n;++i) {printf("\n Enter element no. %d: ",i+1);scanf("%d",p+i);}for(i=0;i<n-1;++i){for(j=i+1;j<n;++j)if(*(p+i)>*(p+j)) {temp=*(p+i);*(p+i)=*(p+j);*(p+j)=temp;}}for(i = 0;i<n;++i){printf("%d\n",*(p+i));}/*free(p)*/ } 結果示例: Enter number of elements in the array: 3 Enter element no. 1: 2 Enter element no. 2: 1 Enter element no. 3: 3 1 2 3free()函數
功能說明:釋放由p指向的內存,被釋放的內存還回給系統,并成為自由內存。
函數原型:void free(void *p)
p:必需是通過malloc、calloc或realloc分配的指針(首地址)
返回值:無
注意:動態分配的內存一定要通過free()函數來釋放,否則會造成內存泄露。
代碼示例:
#include <stdio.h> #include <stdlib.h> int main() {int number,i;int *ptr;printf("How many ints? ");scanf("%d", &number);printf("\n");ptr = (int *) malloc (number*sizeof(int));if(ptr == NULL) { printf("Memory allocation failed.\n");return 1;}for(i=0 ; i<number ; i++){ *(ptr+i) = i;}for(i=number; i>0 ; i--) {printf("%d\n",*(ptr+(i-1)));}free(ptr); //這里記得釋放malloc開辟的內存return 0; }測試結果: How many ints? 5 4 3 2 1 0new和malloc區別
1、屬性
new/delete是C++關鍵字,需要編譯器支持。malloc/free是庫函數,需要頭文件支持。
2、參數
使用new操作符申請內存分配時無須指定內存塊的大小,編譯器會根據類型信息自行計算。而malloc則需要顯式地指出所需內存的尺寸。
3、返回類型
new操作符內存分配成功時,返回的是對象類型的指針,類型嚴格與對象匹配,無須進行類型轉換,故new是符合類型安全性的操作符。而malloc內存分配成功則是返回void * ,需要通過強制類型轉換將void*指針轉換成我們需要的類型。
4、分配失敗
new內存分配失敗時,會拋出bac_alloc異常。malloc分配內存失敗時返回NULL。
5、自定義類型
new會先調用operator new函數,申請足夠的內存(通常底層使用malloc實現)。然后調用類型的構造函數,初始化成員變量,最后返回自定義類型指針。delete先調用析構函數,然后調用operator delete函數釋放內存(通常底層使用free實現)。
malloc/free是庫函數,只能動態的申請和釋放內存,無法強制要求其做自定義類型對象構造和析構工作。
6、重載
C++允許重載new/delete操作符,特別的,布局new的就不需要為對象分配內存,而是指定了一個地址作為內存起始區域,new在這段內存上為對象調用構造函數完成初始化工作,并返回此地址。而malloc不允許重載。
7、 內存區域
new操作符從自由存儲區(free store)上為對象動態分配內存空間,而malloc函數從堆上動態分配內存。自由存儲區是C++基于new操作符的一個抽象概念,凡是通過new操作符進行內存申請,該內存即為自由存儲區。而堆是操作系統中的術語,是操作系統所維護的一塊特殊內存,用于程序的內存動態分配,C語言使用malloc從堆上分配內存,使用free釋放已分配的對應內存。自由存儲區不等于堆,如上所述,布局new就可以不位于堆中。
內存初始化函數 memset()
功能說明:在一段內存中填充某個給定的值(注意填充時 是按照字節順序填充的,而不是按照元素填充)
函數原型:void *memset( void *buffer, char ch, size_t n);
參數:buffer是需要設置的內存的開始地址;
ch是期望填充的值;
n是需要填充的字節數。
返回值:成功時返回buffer的首地址,否則返回NULL
代碼示例:
#include <stdio.h> #include <string.h> int main( ) { char buffer[] = "This is a test of the memset function"; printf( "Before: %s\n", buffer ); memset( buffer, 0, 4 ); //這里的0 意思是將buffer清空printf( "After: %s\n", buffer ); return 0; } 運行結果: Before: This is a test of the memset function After:calloc()函數
功能說明: calloc()與malloc()類似,主要的區別是存儲在已分配的內存空間中的值默認為零
函數原型: void *calloc(size_t num,size_t bytes )
參數:num:要分配內存單元的個數
bytes:每個內存單元的字節大小
返回值:成功時返回內存段首地址,否則返回NULL
代碼示例:
#include <stdio.h> #include <stdlib.h> void main() {float *calloc1;int i;calloc1 = (float *) calloc(3, sizeof(float));if(calloc1!=NULL) {for(i = 0 ; i < 3 ; i++)printf("\ncalloc1[%d]holds%05.5f", i,calloc1[i]);free(calloc1);}else{ printf("Not enough memory \n"); }printf("\n"); }運行結果: calloc1[0]holds0.00000 calloc1[1]holds0.00000 calloc1[2]holds0.00000realloc()函數
功能說明:為已經分配的內存空間重新分配并復制內容;新的空間大小為0時,等價于free函數功能。
函數原型:void *realloc(void *ptr,size_t bytes )
參數:ptr:已分配的內存段首地址
bytes:新申請的內存字節大小
返回值:成功時返回內存段首地址,否則返回NULL
代碼示例:
#include<stdio.h> #include <stdlib.h> int main() {int *ptr , i;ptr = (int *)calloc(5, sizeof(int));if(ptr ==NULL) return 1;*ptr = 1;*(ptr+1) = 2;ptr[2] = 4;ptr[3] = 8;ptr[4] = 16;ptr = (int *)realloc(ptr,7*sizeof(int));if(ptr == NULL) return 1;ptr[5] = 32; ptr[6] = 64;for(i = 0;i < 7;i++){printf("ptr[%d]:%d\n", i, ptr[i]);}realloc(ptr,0); /* free(ptr);*/return 0; } 運行結果: ptr[0]:1 ptr[1]:2 ptr[2]:4 ptr[3]:8 ptr[4]:16 ptr[5]:32 ptr[6]:64總結
以上是生活随笔為你收集整理的C语言—静态存储与动态存储的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 复习笔记(七)——C++友元
- 下一篇: BF算法和KMP算法