realloc失败的几率是多少?

当它耗尽类似于malloc的可用内存时,它是否会失败,还是有其他原因?

任何分配函数( mallocrealloccalloc和on POSIX, posix_memalign )都可能由于以下任何原因而失败,可能还有其他原因:

  • 您已经耗尽了整个虚拟地址空间,或者至少耗尽了它的可用部分。 在32位机器上,只有4GB的地址,可能还有1GB左右的内存供OS内核使用。 即使您的计算机具有16GB的物理内存,单个进程也不能使用超过它的地址。
  • 您没有用尽您的虚拟地址空间,但是您已经将其碎片化得非常糟糕,以至于没有可用的请求大小的连续范围的地址。 如果您成功分配6个512MB块,每隔一个块释放一次,然后尝试分配1GB块,则可能会发生这种情况(在32位计算机上)。 当然,还有很多其他内存大小较小的例子。
  • 您的机器已经耗尽了物理内存,这可能是由于您自己的程序已经使用了它,或者是在机器上运行的其他程序都使用了它。 一些系统(默认配置中的Linux)会过度使用 ,这意味着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; } 

实现可能能够比这更有效地执行特定情况,但是完全如所示的实现是100%正确的。 这意味着realloc(ptr, newsize)可能会在malloc(newsize)失败的任何时候失败; 特别是即使你缩小了分配,它也会失败。

现在,在现代桌面系统上,有一个很好的例子,即不尝试从malloc故障中恢复,而是将malloc包装在一个函数(通常称为xmalloc )中,如果malloc失败,它会立即终止程序; 自然地,相同的论点适用于realloc 。 案例是:

  1. 桌面系统通常以“过度使用”模式运行,其中内核将愉快地分发比RAM + swap支持更多的地址空间,假设程序实际上不会全部使用它。 如果程序确实尝试使用它,它将被强制终止。 在这样的系统上,如果耗尽地址空间 ,malloc将只会失败,这在32位系统上不太可能,在64位系统上几乎不可能。
  2. 即使你没有处于过度使用模式,很可能桌面系统有太多的RAM和交换可用,在你导致malloc失败之前,用户将厌倦了他们的颠簸磁盘并强行终止你的程序。
  3. 没有切实可行的方法来测试分配失败的恢复; 即使你有一个可以精确控制对malloc哪些调用失败的填充程序库(这样的填充程序最多是困难的,最坏的情况是不可能的,创建,取决于操作系统)你必须测试2 N个失败模式的顺序,其中N是程序中对malloc的调用次数。

参数1和2不适用于嵌入式或移动系统(但是!),但参数3在那里仍然有效。

参数3仅适用于必须在每个呼叫站点检查和传播分配失败的程序。 如果您非常幸运地使用C ++,因为它打算使用(即有例外),您可以依赖编译器为您创建错误恢复路径,因此测试负担大大减少。 在任何现在都值得使用的更高级别的语言中,您既有例外又有垃圾收集器,这意味着即使您愿意也不必担心分配失败。

我会说它主要是针对具体实现的。 某些实现可能很可能失败。 有些人可能会在realloc之前使程序的其他部分失败。 始终保持防御并检查它是否失败。

并记得释放你试图重新分配的指针。

 ptr=realloc(ptr,10); 

总是存在内存泄漏。

总是这样做:

 void *tmp=ptr; if(ptr=realloc(ptr,10)==NULL){ free(tmp); //handle error... } 

你有两个问题。

在大多数现代系统中, mallocrealloc失败的可能性微不足道。 只有在虚拟内存不足时才会出现这种情况。 您的系统将无法访问内存而无法保留。

Wrt故障reallocmalloc几乎相同。 realloc可能另外失败的唯一原因是你给它一个不好的参数,那就是没有用mallocrealloc分配的malloc或之前已经free d的malloc

编辑:鉴于R.的评论。 是的,您可以配置系统,使其在分配时失败。 但首先,AFAIK,这不是默认值。 它需要以这种方式配置的权限,作为应用程序程序员,这不是你可以依赖的。 其次,即使你有一个以这种方式配置的系统,这只会在你的可用交换空间被吃掉时出错。 通常,您的机器在此之前很久就会无法使用:它将在您的硬盘上进行机械计算(AKA交换)。