2017-07-28 35 views
-1

例如:當指針值改變時,Heap Scope是否會成功釋放?

void heaptest(){ 
     int *a; 
     a=(int*)malloc(1024*4); 
     int i=1024; 
     while(i--){  
        *a=i; 
        //printf("%d",*a); 
        a++; 
       } 
     free(a); 
       } 

當「一個」被用作指針,假設它指向地址「地址0x20000」。這個堆區的範圍是從0x20000到0x21000。總共4096字節。

while循環後,'a'被指向0x21004,這實際上超出了定義堆的範圍。如果我們釋放堆使用

free(a) 

這個堆將被成功釋放?

對於我的觀察,當我在Visual Studio中使用此func 。它將顯示

Invalid address specified to RtlValidateHeap 

和a的值是0x21004每當是否存在在while循環一個printf()函數的遊離()操作之前。

當我在上使用這個函數STM32F7(Cortex M7)的Keil-MDK時,它只顯示自由操作之前的任何內容。 'a'的值將變爲0x00000;

但是當我添加代碼中顯示的printf()函數。 'a'的值將回到初始值0x20000。

那麼,最後一個問題是,是否可以改變堆指針的值?或在free()操作之前每次將它分配回初始值?

+1

改爲'a = malloc(1024 * sizeof(int));' – yano

+0

這是我見過的最糟糕的長問題之一。它只顯示缺乏基本的OP知識。如果我是他,我會立即刪除它。 –

+0

併購買初學C書。 –

回答

1

你需要釋放你給的地址。你對代碼之間的變量做什麼並不重要。

這是有效的:

char * p = malloc(42); 
p++; 
p--; 
free(p); 

這還有:

char * p = malloc(42); 
char * q = p: 
/* p += 43; */ /* Invokes UB, as making q point more then just one past the object. */ 
q += 42; /* Just one past the allocated memory. */ 
q -= 42; 
free(q); 

這不是

char * p = malloc(42); 
p++; 
free(p); 

這既不是:

char * p = malloc(42); 
p--; 
free(p); 
+1

嚴格地說,例子2調用UB是因爲你增加'p'到超過分配內存的邊界 –

+1

最大增量是* 42 *,而不是43.因爲他們說計算中最困難的事情是緩存失效,命名事物和錯過1錯誤。 –

+0

@IngoLeonhardt:的確如此。固定。 – alk

0

傳遞給free的地址必須爲已作爲malloc/calloc/etc的返回值獲得。傳遞任何其他指針調用undefined behavior

MSDN page for free

自由功能將釋放這是 先前通過向釋放calloc,malloc或realloc一個呼叫分配的內存塊(memblock)。釋放字節的數量相當於在塊被分配(或重新分配,在realloc的情況下)時請求的字節數 。 如果memblock爲NULL,則指針將被忽略並立即自由返回 。試圖釋放無效指針(指向未由calloc,malloc或realloc分配的內存塊 塊的指針)可能會影響 後續分配請求並導致錯誤。原來的指針

跟蹤,以便以後可以將它傳遞給free

void heaptest(){ 
     int *a, a_sav; 
     a=(int*)malloc(1024*4); 
     a_sav = a; // save the original pointer 
     int i=1024; 
     while(i--){  
      *a=i; 
      printf("%d",*a); 
      a++; 
     } 
     free(a_sav); // free the saved pointer 
} 
3

請問這個堆被成功釋放?

這是不可能的。您可以通過將指針值傳遞給free()來調用未定義的行爲,該值不是由malloc()或其他分配函數之一返回的。該可能變成明確釋放指針指向的塊,但更可能它產生一個錯誤,或更糟糕的是:無聲的內存損壞。

特別注意,它是指針重要。存儲指針值的變量(如果有的話)與其沒有直接關係。

我們可以改變堆指針的值嗎?

在這個意義上,指針是,不,你再不能改變它比你可以改變的值爲1,但你可能會導致在該值存儲,而不是包含一個變量不同的價值。你甚至可以通過這種方式來恢復原始值,從而保留釋放分配內存的能力。

0

使用不指向通過malloc分配的地址的參數進行自由調用時,calloc或realloc是未定義的行爲。你完全沒有什麼信息會做什麼。試試這種形式的東西。

void heaptest(){ 
    // Declare a const to make sure we free the right adress in the end 
    int * const a = (int*)malloc(1024*size_of(int)); 
    int i=1024; 
    do { 
     // This will loop from a[0] to a[1024] which is what I assume you meant to do 
     a[1024-i] = i; 
    } while (--i); 
    free(a); 
    } 

這很難說如果這個程序做你想要的。您可以更改我或索引或作業的右側以滿足您的需求,但不要像您那樣進行循環,因爲它更容易出錯。