重分配指向内存的指针后,我可以重复使用它吗?

3

我是C语言的新手。我知道当我使用realloc()函数时,指针被停用了,因为新的内存块可能位于另一个地址(它是否被设置为null?)。但是,指针只是存储地址的值。所以,在此之后我可以重复使用该指针来存储另一个地址吗?此外,我可以这样做吗:

ptr= realloc(ptr, newsize);

1
在编程中,始终对临时指针进行realloc操作,这样如果realloc返回NULL,您就可以恢复,否则会导致内存泄漏。 - undefined
2个回答

4

是的,你可以这样做。这本身并没有什么问题。但是,它可能导致无法从失败的分配中恢复。如果你计划在分配失败时退出程序,这通常并不重要。

所以,下面这个例子是完全可以的:

ptr = realloc(ptr, newsize);
if(!ptr) exit(EXIT_FAILURE);

这也是如此:

tmpptr = realloc(ptr, newsize);
if(!tmpptr) puts("Allocation failed. Continuing anyway.");
else ptr = tmpptr; 

注:是否允许退出时存在内存泄漏可以有争议。在大多数情况下,这并不重要,因为操作系统通常会在退出时清理一切。因此,请注意,在第一个示例中,您将带着内存泄漏退出。
因此,如果内存泄漏对您很重要,即使在失败时退出,您也可以像这样做:
tmpptr = realloc(ptr, newsize);
if(!tmpptr) {
    free(ptr);
    exit(EXIT_FAILURE);
} else {
    ptr = tmpptr; 
}

但是请注意,这只能解决 ptr 指针的问题。如果你有一个比简单的学校作业更复杂的程序,很有可能已经有其他分配了。跟踪所有这些可能,但远非易事。考虑下面这个非常简单的例子:

void foo() {
    void *ptr1 = malloc(SIZE);
    if(!ptr1) exit(EXIT_FAILURE);
    bar();
    free(ptr1);
}

void bar() {
    void *ptr2 = malloc(SIZE);         
    if(!ptr2) {
        // Here we should call free on ptr1 to avoid memory leaks, but how?
        exit(EXIT_FAILURE);
    }
    // Do work
    free(ptr2);
}

当然,您可以轻松地重新编写它:

void foo() {
    void *ptr1 = malloc(SIZE);
    if(!ptr1) exit(EXIT_FAILURE);
    if(!bar()) exit(EXIT_FAILURE);
    free(ptr1);
}

int bar() {
    void *ptr2 = malloc(SIZE);         
    if(!ptr2) return 0;
    // Do work
    free(ptr2);
    return 1;
}

在这个例子中,很容易做到,但请记住,这个例子非常简单。除非我有一个非常好的理由,否则我不会费心去做。这会使代码变得混乱,在现代操作系统上完全没有必要。除非我正在编写需要调用者退出或不退出的函数,否则我只关心它是否重要。
最重要的是,确保程序在退出时释放所有分配的资源可能非常麻烦。除非你有这方面的需求并愿意花费相当多的时间来做对,否则就别费心了。
实际上,处理这个问题需要你考虑设计的几乎所有方面。而这很少是一种好的权衡。
相关问题:_exit()存在内存泄漏风险吗?

这段代码并不完全正确,因为如果realloc失败,它会导致内存泄漏。然而,你的第二个例子是可以的。 - undefined
@AndersK 但这只是一种良性的内存泄漏,所以klutt说得很有道理。 - undefined

1

你可以重复使用它,但是在此之前应该先检查重新分配是否成功。

如果重新分配失败了,那么在之后

ptr= realloc(ptr, newsize);

你丢失了对旧内存块的引用,也就是说,你很可能创建了一个内存泄漏。

你可能想要的是:

void *newptr;
if ( (newptr=realloc(ptr,newsize)) ) ptr = newptr;
else /*handle the error*/;

谢谢。但是在你的例子中,你写了 if (newptr)。这是不是有错呢,因为 newptr 的值不是0或1?你是不是想说 if (!newptr==null) - undefined
@MohammedElbagoury if (newptr)if (newptr!=NULL)if (newptr!=0) 都可以工作。if (X) 通常等同于 if (X!=0):它适用于布尔类型、整数类型,也适用于指针类型,因为整数常量 0 同时充当整数和空指针常量 (NULL)。 - undefined
@MohammedElbagoury 如果你想在代码中明确使用NULL,那么if (!newptr==NULL)不能保证起作用。!的优先级高于==,所以!newptr==NULL实际上是(!newptr)==NULL,它将一个整数(布尔值0或1)与NULL进行比较。NULL可以展开为0,这样就能正常工作,或者它可以展开为((void*)0),这样就会导致约束违规(编译器错误或警告)。NULL之所以奇怪,是因为它可以等同于0。使用显式的(void*)0代替它会更好一些。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接