我是C语言的新手。我知道当我使用realloc()
函数时,指针被停用了,因为新的内存块可能位于另一个地址(它是否被设置为null?)。但是,指针只是存储地址的值。所以,在此之后我可以重复使用该指针来存储另一个地址吗?此外,我可以这样做吗:
ptr= realloc(ptr, newsize);
我是C语言的新手。我知道当我使用realloc()
函数时,指针被停用了,因为新的内存块可能位于另一个地址(它是否被设置为null?)。但是,指针只是存储地址的值。所以,在此之后我可以重复使用该指针来存储另一个地址吗?此外,我可以这样做吗:
ptr= realloc(ptr, newsize);
是的,你可以这样做。这本身并没有什么问题。但是,它可能导致无法从失败的分配中恢复。如果你计划在分配失败时退出程序,这通常并不重要。
所以,下面这个例子是完全可以的:
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;
}
你可以重复使用它,但是在此之前应该先检查重新分配是否成功。
如果重新分配失败了,那么在之后
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)
? - undefinedif (newptr)
,if (newptr!=NULL)
,if (newptr!=0)
都可以工作。if (X)
通常等同于 if (X!=0)
:它适用于布尔类型、整数类型,也适用于指针类型,因为整数常量 0
同时充当整数和空指针常量 (NULL
)。 - undefinedNULL
,那么if (!newptr==NULL)
不能保证起作用。!
的优先级高于==
,所以!newptr==NULL
实际上是(!newptr)==NULL
,它将一个整数(布尔值0或1)与NULL
进行比较。NULL
可以展开为0
,这样就能正常工作,或者它可以展开为((void*)0)
,这样就会导致约束违规(编译器错误或警告)。NULL
之所以奇怪,是因为它可以等同于0
。使用显式的(void*)0
代替它会更好一些。 - undefined