首页 > 解决方案 > 为什么 free(arr) 只删除数组的前两个元素?

问题描述

我有一个简单的代码:

#include  <stdio.h>
#include  <stdlib.h>

int main(void)
{
    int elms = 5;
    int* a = (int*) calloc(elms, sizeof(int));

    *a = elms;
    for(int i = 1; i < elms; i++){
        *(a + i) = i;
    }

    for(int i = 0; i < elms; i++){
        printf("%d ", *(a + i));
    }

    printf("\n");

    free(a);
    // create new array with size increased by one
    int* arr = (int*) realloc(a, (elms + 1) * sizeof(int));
    *(arr + elms) = 10;

    for(int i = 0; i < elms + 1; i++){
        printf("%d ", *(arr + i));
    }

    printf("\n");    

    return 0;
}

在 rextester 上运行

在这里,我得到的输出为:

5 1 2 3 4 
0 0 2 3 4 10 

我的问题是为什么调用free()只删除数组的前两个元素?它应该只删除第一个元素,或者所有元素,但为什么要删除两个元素?

如果我评论对 的调用free(),我会得到预期的输出:

5 1 2 3 4 
5 1 2 3 4 10 

注意:如果我按预期将reallocback的值重新分配给 ,则输出没有变化。a

标签: cmallocrealloc

解决方案


您使用以下方法调用未定义的行为:

free(a);
// create new array with size increased by one
int* arr = (int*) realloc(a, (elms + 1) * sizeof(int));

根据7.22.3.5 The realloc function,C 标准的第 3 段(加粗矿):

如果 ptr 与内存管理函数先前返回的指针不匹配,或者如果空间已通过调用freeorrealloc函数被释放,则行为未定义。


推荐阅读