指针值更改后,是否可以成功释放堆范围?

时间:2017-07-28 15:41:02

标签: c visual-studio stm32 keil

例如:

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

当' a'被用作指针,假设它指向地址" 0x20000"。并且此堆区域的范围是从0x20000到0x21000。总共4096字节。

在while循环之后,' a'被指向0x21004,这实际上超出了已定义堆的范围。如果我们使用

释放堆
free(a)

这个堆会成功释放吗?

对于我的观察,当我在Visual Studio 中使用此功能时。它会显示

Invalid address specified to RtlValidateHeap
只要在while循环中有printf()函数,

并且在free()操作之前a的值为0x21004。

当我在 Keil-MDK for STM32F7(Cortex M7)上使用此功能时,它只显示空闲操作之前的内容。 ' a'的价值将变为0x00000;

但是当我添加代码中显示的printf()函数时。 ' a'的价值将返回初始值0x20000。

所以,最后一个问题是,我们可以更改堆指针的值吗?或者每次在free()操作之前将其分配回初始值?

4 个答案:

答案 0 :(得分:3)

  

这个堆会被成功释放吗?

不可能说。通过将指针值传递给free()未由malloc()或其他分配函数返回的does not begin with 15.来调用未定义的行为。那个可以显示为释放指针指向的块,但更可能产生错误,或者更糟糕的是:无声内存损坏。

请特别注意,重要的是指针。存储指针值的变量(如果有的话)与它没有直接关系。

  

我们可以更改堆指针的值吗?

在指针是的意义上,不,你不能再改变它而不是你可以改变值1.但你可以导致一个存储该值的变量代替包含不同的值。您甚至可以以允许恢复原始值的方式执行此操作,以便保留释放已分配内存的功能。

答案 1 :(得分: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);

答案 2 :(得分:0)

传递给free 的地址必须已作为malloc / calloc /等的返回值获取。传递任何其他指针会调用undefined behavior

来自MSDN page for free

  

free函数释放一个内存块(memblock)   先前通过调用calloc,malloc或realloc分配的。该   释放的字节数等于请求的字节数   当块被分配(或重新分配时,在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 :(得分:0)

使用不指向通过malloc,calloc或realloc分配的地址的参数调用free是未定义的行为。你完全没有关于它将做什么的信息。尝试这种形式的东西。

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);
    }

很难说这个程序是否符合您的要求。您可以更改i或分配的索引或右侧以满足您的需要,但不要像您那样进行循环,因为它更容易出错。