c-为什么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 

注意:如果按预期将realloc的值重新分配回a,则输出不会发生变化。

您使用调用未定义的行为

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

根据7.22.3.5 realloc函数,C标准第3段(粗体矿(:

如果ptr与内存管理函数早些时候返回的指针不匹配,或者如果通过调用freerealloc函数释放了空间,则行为未定义。

您的代码有未定义的行为。具体而言:

free(a);
... realloc(a, ...);

free(a)之后,a的值是不确定的。试图用它做任何事情(例如将它传递给函数(都有未定义的行为。

任何结果都是允许的。

除了其他答案:

你可能想要这个:

#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");
  // << don't call free(a) here, once you've done that
  //    a is "gone" forever.
  // create new array with size increased by one
  // << we use the same variable a as before, using another
  //    variable arr as you did is useless and confusing
  a = (int*)realloc(a, (elms + 1) * sizeof(int));
  *(a + elms) = 10;
  for (int i = 0; i < elms + 1; i++) {
    printf("%d ", *(a + i));
  }
  free(a);  // << call free(a) here once you're done with a
  printf("n");    
  return 0;
}

查看以<< 开头的注释

输出:

5 1 2 3 4
5 1 2 3 4 10

相关内容

  • 没有找到相关文章

最新更新