R..*_*R.. 11
任何的分配功能(malloc,realloc,calloc,和POSIX, posix_memalign)可能失败对于任何的下列原因,以及其它可能的:
malloc在这种情况下不会失败,但是当OS计算出没有足够的物理内存时,操作系统将会杀死一个或多个程序.但是在健壮的系统(包括禁用过度使用的Linux)上,malloc如果没有物理内存,则会失败.请注意,严格来说,分配函数可以随时以任何理由失败.最小化失败是一个实施质量问题.realloc即使减小对象的大小,也可能会失败; 这可能发生在严格按大小分配分配的实现上.当然,在这种情况下,您可以继续使用旧的(较大的)对象.
你应该认为是realloc这样工作的:
void *realloc(void *oldptr, size_t newsize)
{
size_t oldsize = __extract_size_of_malloc_block(oldptr);
void *newptr = malloc(newsize);
if (!newptr)
return 0;
if (oldsize > newsize)
oldsize = newsize;
memcpy(newptr, oldptr, oldsize);
free(oldptr);
return newptr;
}
Run Code Online (Sandbox Code Playgroud)
一个实现可能能够比这更有效地处理特定情况,但完全按照所示工作的实现是 100% 正确的。这意味着realloc(ptr, newsize)可能会失败任何时候malloc(newsize)都会失败;特别是即使您正在缩小分配,它也可能会失败。
现在,在现代桌面系统上,有充分的理由不要尝试从malloc故障中恢复,而是包装malloc在一个函数(通常称为xmalloc)中,如果malloc失败则立即终止程序;自然,同样的论点适用于realloc。案例是:
malloc失败之前很久,用户就会厌倦他们的磁盘抖动并强行终止您的程序。malloc失败的 shim 库(这些 shim 最多很难创建,最坏情况下不可能创建,具体取决于操作系统),您也必须测试 2 N 个失败模式的顺序,其中 N 是在你的程序中调用 malloc 的次数。论点 1 和 2 不适用于嵌入式或移动系统(但!)但论点 3 在那里仍然有效。
参数 3 仅适用于必须在每个调用站点检查和传播分配失败的程序。如果您很幸运地使用 C++,因为它打算使用(即有例外),您可以依靠编译器为您创建错误恢复路径,因此测试负担会大大减少。并且在当今值得使用的任何高级语言中,您都有异常和垃圾收集器,这意味着即使您愿意,也不必担心分配失败。
我想说它主要是特定于实现的。有些实施很可能会失败。有些可能会在重新分配之前使程序的其他部分失败。始终保持防御状态并检查是否失败。
并记住释放您尝试重新分配的旧指针。
ptr=realloc(ptr,10);
Run Code Online (Sandbox Code Playgroud)
总是可能存在内存泄漏。
总是这样做:
void *tmp=ptr;
if(ptr=realloc(ptr,10)==NULL){
free(tmp);
//handle error...
}
Run Code Online (Sandbox Code Playgroud)