Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
realloc()的正确用法_C_Memory Leaks_Dynamic Memory Allocation_Realloc_Calloc - Fatal编程技术网

realloc()的正确用法

realloc()的正确用法,c,memory-leaks,dynamic-memory-allocation,realloc,calloc,C,Memory Leaks,Dynamic Memory Allocation,Realloc,Calloc,来自man realloc:realloc()函数返回一个指向新分配内存的指针,该指针针对任何类型的变量进行适当对齐,可能与ptr不同,如果请求失败,则返回NULL 因此,在这段代码片段中: ptr = (int *) malloc(sizeof(int)); ptr1 = (int *) realloc(ptr, count * sizeof(int)); if(ptr1 == NULL){ //reallocated pointer ptr1 printf("Ex

来自man 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                     
}
仅仅假设重新分配的指针指向不同的内存块而不是同一个内存块就足够了。因为如果假设变为false,realloc返回ptr指向的原始内存块的地址,然后执行free(ptr)(出于注释中给出的原因)然后,内存块将被擦除,程序将崩溃。
我是否应该设置另一个条件来比较ptr和ptr1的相等性,并排除free(ptr)语句的执行?

如果
realloc
移动数据,它将在幕后为您释放旧指针。我没有C11标准的副本,但它在C99标准中有保证。

OP:。。。可能与ptr不同,如果请求失败,则为NULL。
A:不总是这样<如果
count
为0,则可以合法返回code>NULL(不是失败)

OP:仅假设重新分配的指针指向不同的内存块而不是同一块就足够了。
A:没有

OP:我是否应该加入另一个条件来比较ptr和ptr1的相等性,并排除自由(ptr)语句的执行?
A:没有

如果
realloc()
返回
NULL
(计数不是0),则
ptr
的值仍然有效,指向未调整大小的数据<代码>免费(ptr)是否免费取决于您的目标

如果
realloc()

例如:

#包括
#包括
int ReallocAndTest(字符**Buf,大小\u t新闻大小){
断言(Buf);
void*NewBuf=realloc(*Buf,NewSize);
如果((NewBuf==NULL)和&(NewSize>0)){
return 1;//返回失败
}
*Buf=NewBuf;
返回0;
}
只要不要在快乐路径中调用原始ptr上的
free()
。实际上,
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
}

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

根据下面的好评论,将修复应用为编辑

阅读,揭示了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)
    ,因为
    ptr
    tmp
    指向同一位置。另外,为了安全起见,我确保将
    NULL
    分配给
    tmp
    ,以避免
    tmp
    在范围内时出现任何悬空指针问题。

    如果
    realloc
    成功,您不应该
    释放您的原始指针。如果
    realloc
    失败,您是否释放该指针取决于特定应用程序的需要;如果您在没有额外内存的情况下绝对无法继续,那么这将是一个致命错误,您将取消分配任何保留的存储并退出。如果,OTOH,您仍然可以继续(可能执行不同的操作,并希望稍后内存可用),您可能希望保留该内存,稍后尝试另一个
    realloc

    :

    7.22.3.5 realloc功能

    概要

    1
    #包括
    void*realloc(void*ptr,size\u t size)
    描述

    2
    realloc
    函数取消分配由
    ptr
    指向的旧对象,并返回 指向新对象的指针,该对象的大小由
    size
    指定。新报告的内容 对象应与解除分配前的旧对象相同,以较小者为准 新的和旧的尺寸。新对象中超出旧对象大小的任何字节都将被删除 不确定值

    3如果
    ptr
    是空指针,则
    realloc
    函数的行为与 指定尺寸。否则,如果
    ptr
    与内存先前返回的指针不匹配 管理功能,或者如果通过调用
    空闲
    释放空间,或者
    realloc
    函数,行为未定义。如果无法创建新对象的内存 分配后,旧对象不会被解除分配,其值不变

    返回

    4
    realloc
    函数返回指向新对象的指针(该对象可能具有相同的 值作为指向旧对象的指针),或者如果无法创建新对象,则为空指针 分配的


    重点补充。注:第4条;返回的指针可能与原始指针相同

    PS-我没有足够的代表点在另一个类似的问题上问这个问题,所以我不得不形成一个新的问题..那里有一个问题:如果ptr为空,自由(ptr)做什么
    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;
    
         #include <stdlib.h>
         void *realloc(void *ptr, size_t size);