realloc释放现有的内存?

Sum*_*aik 2 c pointers

我试图在下面的程序中使用realloc重新分配内存,并在realloc初始内存后检查我使用malloc(i =(int*)malloc(5*sizeof(int)))仍然存在与否,使用下面的程序我能够在使用另一个指针(即*m)检查的realoc之后访问数据.这是正确的行为吗?一旦realloc调用,内存应该是免费的吗?

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

    int main()
    {
       int *i,*jn, *m;
       i = (int*)malloc(5 * sizeof(int));
       int j,k=10;

      for(j=0 ;j<5; j++)
      {
         i[j] = j;
         printf("%d \n",i[j]);
      }

      for(j=0 ;j<5; j++)
      {
        printf("%p\n",i++);
      }

      jn = (int *)calloc(5, sizeof(*i));

      for(j=0 ;j<5; j++)
      {
         printf("%p\n",jn++);
      }

       i = i-5;
       m = i;

      printf("m = %p  %d\n",(m+1), *(m+1));

      i =(int *)realloc(i,8*sizeof(int));

      for(j=0 ;j<8; j++)
      {

         printf("%d\n",i[j]);
      }

      for(j=0 ;j<8; j++)
      {

        printf("%p\n",i++);
      }
      printf("m = %p  %d\n",(m+1), *(m+1));

      return 0;
}
Run Code Online (Sandbox Code Playgroud)

Art*_*Art 9

realloc相当于:

void *
realloc(void *old, size_t newsz)
{
    size_t old_sz = internal_function_that_finds_old_size(old);
    void *new = malloc(newsz);
    if (new == NULL)
        return NULL;
    memcpy(new, old, oldsz);
    free(old);
    return new;
}
Run Code Online (Sandbox Code Playgroud)

realloc可以做一些更有效的事情,包括不改变指针而只是使分配的大小更大,它可以使用内核设施将内存映射到其他地方以避免复制等。但一般来说realloc应该被视为完全按照我上面写的那样做,因为这是最坏情况的行为。

现在,说到你的程序。你通过无效的指针接触内存,任何事情都有可能发生。m调用后不再是有效指针realloc。这并不意味着任何人都会阻止您使用它,它只是意味着如果您确实使用它,您的程序将不再保证做任何明智的事情。

  • 啊,“新”以蓝色突出显示! (5认同)
  • @MatteoItalia 呵呵。我猜 SO 上的语法高亮相信 C/C++ 神话。 (2认同)

AnT*_*AnT 6

首先,realloc可能会决定

  1. 分配新的内存块,复制数据并释放原始内存块,或

  2. 只需"原位"扩展/收缩原始块,而无需分配新块.

它将选择哪种方法取决于实施和各种其他外部因素.它可能遵循第一种方法.或者它可能遵循第二种方法.您可以通过比较指针im之后的值来轻松找出它遵循的方法realloc.

其次,如果realloc决定遵循第一种方法(即分配一个新的内存块),那么旧的块确实被释放了realloc.在这种情况下,尝试访问原始内存位置会导致未定义的行为.

如果realloc决定采用第二种方法(即扩大或缩小"到位"原来的内存块),然后mi将继续指向同一个位置.在这种情况下,看到相同的数据并不奇怪m.

PS这意味着代码的行为要么是微不足道的,要么是未定义的.它不能真正用于分析行为是否"正确".如果内存确实被释放,你期望发生什么?

  • C11标准说(§7.22.3.5):_`realloc`函数释放`ptr`指向的旧对象,并返回一个指向由`size`指定大小的新对象的指针....如果无法分配新对象的内存,则不会释放旧对象,并且其值不会更改....`realloc`函数返回一个指向新对象的指针(可能与指向旧对象的指针具有相同的值),如果无法分配新对象,则返回空指针._ C99也是如此.C90没有明确说明旧的内存被释放,不像C99和C11那样. (2认同)
  • @JonathanLeffler在描述`realloc`c的行为时总是有一定的概念价值,因为它总是(至少在内部)释放旧的内存,但是这个问题似乎主要涉及到`realloc`完成工作后该内存的状态。对于外部观察者(在此问题的上下文中),是否释放内存块然后在同一位置分配内存块,或者只是“就地”扩展/收缩,可能并不重要。 (2认同)