realloc的正确使用()realloc的正确使用()(Proper usage of reall

2019-05-12 01:57发布

从人的realloc:本realloc()的函数返回一个指向新分配的存储器,其被适当地用于任何种类的变量的对准并且如果请求失败可能是从PTR不同,或NULL。

因此,在这个代码片段:

ptr = (int *) malloc(sizeof(int));
ptr1 = (int *) realloc(ptr, count * sizeof(int));
if(ptr1 == NULL){           //reallocated pointer ptr1
    printf("Exiting!!\n");
    free(ptr);
    exit(0);
}else{
    free(ptr);          //to deallocate the previous memory block pointed by ptr so as not to leave orphaned blocks of memory when ptr=ptr1 executes and ptr moves on to another block
    ptr = ptr1;         //deallocation using free has been done assuming that ptr and ptr1 do not point to the same address                     
}

是否足以只是假设重新分配的指针指向memeory的不同的块,而不是同block.Because如果假设为假和realloc返回原来的内存块的地址由ptr指向,然后免费(PTR)执行(在评论中给出的原因),那么内存块将被擦除,程序会去坚果。 我应该把其中将比较PTR和PTR1的平等和排除免费(PTR)语句的执行另一个条件?

Answer 1:

只是不叫free()在幸福路原来的PTR。 从本质上讲realloc()做,对你。

ptr = malloc(sizeof(int));
ptr1 = realloc(ptr, count * sizeof(int));
if (ptr1 == NULL) // reallocated pointer ptr1
{       
    printf("\nExiting!!");
    free(ptr);
    exit(0);
}
else
{
    ptr = ptr1;           // the reallocation succeeded, we can overwrite our original pointer now
}


Answer 2:

应用修复作为编辑,基于下面的好评。

阅读这个comp.lang.c问题 ,揭示了三种情况:

  1. “当它能够,它只是让你回你递给它相同的指针。”
  2. “但如果它必须去记忆一些其他部分找到足够的连续空间,它会返回一个不同的指针(与先前的指针值将变得不可用)。”
  3. “如果realloc可能根本找不到足够的空间,它返回一个空指针,并保留所分配的过去的区域。”

这可以直接翻译成代码:

int* ptr = (int*)malloc(sizeof(int));
int* tmp = (int*)realloc(ptr, count * sizeof(int));
if(tmp == NULL)
{
    // Case 3, clean up then terminate.
    free(ptr);
    exit(0);
}
else if(tmp == ptr)
{
    // Case 1: They point to the same place, so technically we can get away with
    // doing nothing.
    // Just to be safe, I'll assign NULL to tmp to avoid a dangling pointer.
    tmp = NULL;
}
else
{
    // Case 2: Now tmp is a different chunk of memory.
    ptr = tmp;
    tmp = NULL;
}

所以,如果你仔细想想,你发布的代码是罚款(几乎)。 上面的代码简化为:

int* ptr = (int*)malloc(sizeof(int));
int* tmp = (int*)realloc(ptr, count * sizeof(int));
if(tmp == NULL)
{
    // Case 3.
    free(ptr);
    exit(0);
}
else if(ptr != tmp)
{
    ptr = tmp;
}
// Eliminate dangling pointer.
tmp = NULL;

注意额外else if(ptr != tmp)排除案例1,你不会想拨打free(ptr)因为ptrtmp指的是同一位置。 此外,只是为了安全,我保证分配NULLtmp ,以避免任何悬摆指针的问题,同时tmp是在范围内。



Answer 3:

OP:...如果请求失败,则可能是从PTR不同,或NULL。
答:不一定。 NULL可以合法地返回(未失败),如果count为0。

OP:是否足以只是假设重新分配的指针指向的内存不同的块,而不是相同的块。
答:没有

OP:我应该把其中将比较PTR和PTR1的平等和排除免费(PTR)语句的执行另一个条件?
答:不可以。

如果realloc()返回NULL (和计数不为0),价值ptr仍然有效,指着未调整的数据。 free(ptr)或不取决于你的目标。

如果realloc()返回不NULL ,不free(ptr)它是所有准备好释放。

例如: https://codereview.stackexchange.com/questions/36662/critique-of-realloc-wrapper

#include <assert.h>
#include <stdlib.h>

int ReallocAndTest(char **Buf, size_t NewSize) {
  assert(Buf);
  void *NewBuf = realloc(*Buf, NewSize);
  if ((NewBuf == NULL) && (NewSize > 0)) {
    return 1;  // return failure
  }
  *Buf = NewBuf;
  return 0;
}


Answer 4:

realloc将返回相同的地址, ptr ,如果它有足够的空间来扩展的内存指出实际块ptr 。 否则,将数据移动到新的块并释放旧块。 你不能靠ptr1是不同的,以ptr 。 你的程序的行为未定义。

如果realloc返回另一个地址,它首先将释放旧的,所以你不必自己做。

顺便说一句,从来不投的回报率malloc/realloc :)。 您的代码应该是这样的:

ptr=malloc(sizeof(int));
ptr=realloc(ptr,count*sizeof(int));
if(ptr==NULL)
{   
    // error!    
    printf("\nExiting!!");
    // no need to free, the process is exiting :)
    exit(0);
}


Answer 5:

如果realloc移动你的数据时,它会释放幕后的老猎狗为您服务。 我没有C11标准的副本,但它是在C99标准保证的。



Answer 6:

应该free ,如果你原来的指针realloc成功。 无论您free该指针如果realloc失败,取决于特定应用的需求; 如果你绝对不能继续没有额外的内存,那么这将是一个致命的错误,你会解除分配任何存储持有和退出。 如果OTOH,你仍然可以继续(也许执行不同的操作,并希望将内存可用来后),你可能想坚持到内存和尝试一个又一个realloc后。

引经据典 :

7.22.3.5的realloc函数

概要

1
  #include <stdlib.h> void *realloc(void *ptr, size_t size); 

描述

2 realloc功能将释放旧的对象通过指向ptr并返回一个指针,指向具有由Ed大小SPECI连接一个新的对象size 。 新对象的内容应是相同于解除分配现有旧的对象的,要由新老尺寸中的较小者。 在超越老对象的大小新对象的任何字节有不确定的值。

3如果ptr为空指针,则realloc功能的行为类似于malloc用于SPECI音响版尺寸的功能。 否则,如果ptr不匹配的指针早些时候内存管理功能恢复,或者如果空间已经通过向呼叫释放freerealloc功能,其行为定义理解过程网络。 如果新对象的内存无法分配,旧的对象是不释放其价值是不变的。

返回

4 realloc函数返回一个指针到新对象(其可以具有相同的值作为一个指针,指向旧的对象),或一个空指针如果新对象无法进行分配。

着重强调。 注意第4; 返回的指针可能是一样的你原来的指针。



文章来源: Proper usage of realloc()