2017-07-28 96 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); 
    } 

这很难说如果这个程序做你想要的。您可以更改我或索引或作业的右侧以满足您的需求,但不要像您那样进行循环,因为它更容易出错。