1. 程式人生 > >關於free如何知道要釋放記憶體空間的長度問題

關於free如何知道要釋放記憶體空間的長度問題

在學記憶體分配的問題的時候,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下就明瞭了~~~


FROM:  http://www.2cto.com/kf/201212/174775.html

相關推薦

關於free如何知道釋放記憶體空間長度問題

在學記憶體分配的問題的時候,malloc和calloc都要指定需要分配記憶體的大小,但是free的就不需要,我就納悶free是咋知道從指標地址開始的多少長度是被分配了的? 當時就想,在malloc或者calloc的時候,編譯器應該把大小的數值放到哪個地方了,當free

STM32移植cJSON注意free釋放記憶體

如題: 關於怎麼移植的 網上有很多參考文件,也很簡單,因為cjson只有2個檔案,一個cJSON.c 一個cJSON.h檔案。 關於如何釋放記憶體,自己除錯的時候也是搜了度娘,網上好多方法並不正確,故寫下此文件 使用時的流程是: cJSON * root;

[CareerCup] 13.9 Aligned Malloc and Free Function 寫一對申請和釋放記憶體函式

13.9 Write an aligned malloc and free function that supports allocating memory such that the memory address returned is divisible by a specific power of

在子函式中malloc分配記憶體free釋放記憶體的方法(基於C)

1. 子函式malloc分配記憶體        為了增強程式可讀性,有時會在子函式中malloc分配記憶體。測試瞭如下三種方法,容易想到的是第一種。事實證明這種也是錯誤的! #include <stdio.h> #include &l

為什麼連結串列操作過程中對於結構體指標,都用malloc來開闢記憶體空間

在使用上,malloc 和 new 至少有兩個不同: new 返回指定型別的指標,並且可以自動計算所需要大小。比如: 在使用上,malloc 和 new 至少有兩個不同: new 返回指定型別的指標,並且可以自動計算所需要大小。比如: 1 2 3

stm32 移植cJson 注意free釋放記憶體!!

如題: 關於怎麼移植的網上有很多參考文件,也很簡單,因為cjson只有2個檔案,一個cJSON.c 一個cJSON.h檔案。 我用的是原子的stm32 工程檔案測試,他們有自己定義的malloc.c      malloc.h,很方便可以直接用。 需要修改的就是下面:把原

動態連結串列的建立、節點記憶體空間申請以及釋放

1.動態連結串列的初始化: typedef struct _STACK{     void* data;     int size;     struct _STACK* next;     struct _STACK* pre;} STACK; STACK *stack;

C 語言執行free()釋放記憶體時 報錯

今天遇到了一個問題。先用malloc()分配一定大小的記憶體,然後在主函式最後要對這些記憶體進行釋放。呼叫free函式,執行報錯。單步除錯 執行free()後的報錯如圖 1所示。 最終發現我是這樣做的:例如 分配10個元素記憶體,我對這10個元素進行了賦值,最後是呼叫了fr

清理/var/spool/clientmqueue目錄釋放大量空間

無法 無法刪除 文件太大 命令 args 需要 long clientm rm -rf 清理/var/spool/clientmqueue目錄可以釋放大量空間,具體命令是:ls | xargs rm -f 文件太大,rm -rf會由於參數太多而無法刪除,所以需要用上面的命令

Python真的無所不能!連黑客技術都用它!你知道用哪些技術嗎

獲取 ctypes env 應用 轉儲 apt 當前 發行版 社區 網絡愛好者總是要掌握編程語言的,這裏推薦:python。下面,一文了解黑客們會用到哪些Python技術! 進群:548377875 即可獲取數十套PDF哦! 安裝依賴包 很多時候讀者們會

C語言中free()函數釋放struct結構體中的規律

void poi inf clu main 圖片 刪除 動態分配 不同 並不是什麽新鮮的事情,不過值得註意。首先我們知道,在使用struct來定義並聲明一個變量時,將會自動劃分出一個連續的儲存空間(雖然根據某些對齊原則會出現內存間隙,但是大體上來說還是連續的)這一塊連續空間

基礎知識之jvm記憶體空間

Java基礎知識之jvm記憶體空間 1 JVM記憶體空間有哪些分割槽? 堆 方法區 JAVA虛擬機器棧 程式計數器 本地方法棧 堆空間(HEAP):是建立物件的例項和陣列都存放的記憶體空間,是隨著虛擬機器的啟動而建立的,它是

11.1 js中級,資料型別、資料儲存方式、作用域記憶體空間的區別以及例識別。

一. 基本資料型別和引用資料型別的區別。     1.基本資料型別:基本資料型別就是簡單的操作值。     2.引用資料型別:就是把引用的地址賦給變數。   堆記憶體:     就是存放程式碼塊的,存放形式有兩種       1)物件以鍵值對的形式存放       2)引用資料型別的賦值,是把引用

vector 釋放記憶體需不需要delete

是否需要delete是看你有沒有用new. 具體的幾個例子說明: vector<int> vIntList; //這個是不用delete的. vector<char*> vPointList; char 

C#釋放記憶體的方法

原文:https://blog.csdn.net/zsy619/article/details/79181719 ---------------------  如何釋放記憶體: [DllImport("kernel32.dll", EntryPoint = "SetProcessWork

關於記憶體地址和記憶體空間的理解。

VIPler 關於記憶體地址和記憶體空間的理解。 1.記憶體地址用4位16進位制和8位16進製表示的區別。例如經常可以看到某些書籍上寫的記憶體地址0x0001,在另外一

程序的記憶體空間相互隔離

#子程序 和 父程序 的名稱空間時相對獨立的! # x = 1000 # def task(): # time.sleep(3) # global x # x = 123 # print('哈哈哈') # # if __name__ == '__main__': #

Linux伺服器釋放記憶體指令碼

1)在root目錄下建立一個freemem.sh的指令碼: vi freemem.sh #!/bin/bash used=`free -m | awk 'NR==2' | awk '{print $3}'` free=`free -m | awk 'NR==2' | awk '{print

swap自動釋放記憶體

#free -mh 如上圖,一般情況下不會用到swap的,一般實體記憶體使用在90%以上(預設是這個數,可以自行在/etc/sysctl.conf裡設定vm.swappiness引數),但有的時候,記憶體會被快取佔用,導致系統開始使用swap空間,此時就需要清理下swap了 這裡先說下vm.swap

C++ Primer Plus書之--C++指標及使用new分配記憶體,使用delete釋放記憶體

先來個簡單的程式初步認識一下指標  #include "iostream" using namespace std; int main() { // 定義一個int型變數 int num = 123; // 定義一個int型指標變數 int * p_num; // 指標指向