程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> 關於free如何知道要釋放內存空間的長度問題

關於free如何知道要釋放內存空間的長度問題

編輯:關於JSP

在學內存分配的問題的時候,malloc和calloc都要指定需要分配內存的大小,但是free的就不需要,我就納悶free是咋知道從指針地址開始的多少長度是被分配了的?

當時就想,在malloc或者calloc的時候,編譯器應該把大小的數值放到哪個地方了,當free的時候就去找那個數值,釋放掉數值大小的堆空間。

但是到底放哪呢?

前幾天在網上一陣亂逛,說是現代編譯器就是把大小的數值放在分配地址開始的之前位置,但是具體在之前多少位置呢?今天在vs的內存監視器裡面看到了。

測試代碼如下:

[cpp] 
#include "stdlib.h" 
#include "stdio.h" 
 
#define Num 100 
 
int main(void) 

    int i; 
    int *p=(int *)malloc(Num); 
    for (i=0;i<Num;i++) 
    { 
        *(p+i)=1;   //賦值為1只是為了看起來方便 
    } 
    free(p); 
 
    return 0; 

其中p的地址為0x00393220
接著打開vs2008的內存監視器窗口看:


有一個地址為0x00393210的很可疑,因為0x64=100

那麼改一下看看:

[cpp] 
#define Num 50 
再看內存監視器:


看到*(0x00393210)=0x32;即0x32=50

那應該就是把大小放這裡了,就是說距離分配地址0x10之前的位置。

從中可以看出為什麼分配堆更號內存大小(當然它的主要方面還是“碎片”的產生)的一個小方面~~~

那麼calloc又是如何呢?答案就是和malloc一樣,把原來的size換成num*size;

[cpp]
#include "stdlib.h" 
#include "stdio.h" 
 
#define Num 50 
 
int main(void) 

    int i; 
    int *p=(int *)calloc(Num,Num); 
    for (i=0;i<Num;i++) 
    { 
        *(p+i)=1; 
    } 
    free(p); 
 
    return 0; 

這裡的p地址是0x00395008。

0x9c4=2500(這裡有大小端的知識,呵呵,可以看出來x86是小端:MSB存高地址)

這對於存放內存空間大小的數值是足夠的,因為calloc和malloc的函數原型:

[cpp] 
void *malloc(size_t size); 
void *calloc(size_t num,size_t size); 
ps:size_t在內部被宏定義為unsigned int。

這樣豈不是說calloc可以把整個內存都分配了,那當然不行,如何你申請的堆內存空間過大,則會發生以下錯誤(vs2008):

 

中間那句話很簡潔明了吧,至於我輸了多大的值,大家可以試試,其實話說在ARM和DSP(針對MCU),堆和棧的大小和起始地址都是可以手動分配的,你當然不能超過了~~~

但是還有問題:是不是存大小的位置和編譯器有關呢?和CPU有關否?

To Be Continued~~~

ps:手中剛好有一塊Cortex-M3的板子,可以用MDK來編譯Debug下就明了了~~~

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved