如果一个malloc
分配失败,我们应该再试试吗?
在这样的事情:
char* mystrdup(const char *s)
{
char *ab = NULL;
while(ab == NULL) {
ab=(char*)malloc(strlen(s)+1);
}
strcpy(ab, s);
return ab;
}
是while循环的有效检查内存分配?
如果一个malloc
分配失败,我们应该再试试吗?
在这样的事情:
char* mystrdup(const char *s)
{
char *ab = NULL;
while(ab == NULL) {
ab=(char*)malloc(strlen(s)+1);
}
strcpy(ab, s);
return ab;
}
是while循环的有效检查内存分配?
一般情况下,一个现代malloc()
实现将返回NULL
只能作为一个绝对的最后手段,并试图再次肯定不会帮助。 这将有助于唯一被释放一些内存 ,然后再次尝试。 如果您的应用程序保存的任何资源消耗,这将是他们自由的时间,然后给它一个镜头。
在某些环境中,一个有用的做法是分配的少量内存作为应急基金 。 如果malloc()
永远不会返回NULL
,则可以释放一个应急基金,然后分配任何你需要的资源,能够处理错误,并优雅地退出。 这是与旧的Macintosh工具箱编程时的普遍做法; 如果malloc()
返回NULL
,你可以使用的空间创建一个对话框退出之前报告的问题。
在单线程程序“再次尝试”而不释放任何内存之间尝试毫无实际意义。 它只会永远循环下去。
在多线程程序,这可能“工作”,如果另一个线程并行运行突然决定释放一些自己的记忆。 在这种情况下,循环将构成经典的“忙等待”循环。 但即使在这种情况下,这样的代码有不止一个原因是非常实用价值不大。
没有永不。 如果malloc
返回NULL,表示有错误,你可能应该退出。
没有争论为什么或什么时候这将是有益的,尝试重新分配在一个循环中可以工作,至少在Windows 64位编码,默认页面文件设置。 此外,这可能会购买更多的出奇额外的虚拟内存。 虽然,不要在一个无限循环做到这一点,而是使用重试的数量有限。 作为一个证明,试试下面的代码一种模拟泄漏1 MB的内存。 你必须在发布版本中运行它,最好不要在调试器下。
for (int i = 0; i < 10; i++)
{
size_t allocated = 0;
while (1)
{
void* p = malloc(1024 * 1024);
if (!p)
break;
allocated += 1;
}
//This prints only after malloc had failed.
std::cout << "Allocated: " << allocated << " Mb\n";
//Sleep(1000);
}
在我的机器内存和系统管理页面文件的8 GB,我得到下面的输出(与VS2013建为64的目标,在Windows 7专业测试):
Allocated: 14075 Mb
Allocated: 16 Mb
Allocated: 2392 Mb
Allocated: 3 Mb
Allocated: 2791 Mb
Allocated: 16 Mb
Allocated: 3172 Mb
Allocated: 16 Mb
Allocated: 3651 Mb
Allocated: 15 Mb
我不知道这样的行为的确切原因,但似乎分配开始一次未能页面文件大小调整不能请求跟上。 在我的机器,页面文件从8 GB到20 GB,增长这个循环之后(在程序退出后回落到8 GB)。
这是令人难以置信的可能性不大,这将做你想做的; 如果你的内存不足,忙循环,直到你获得更多的可能是令人失望的。 你应该只返回NULL给调用程序,以便它可以处理资源耗尽,无论是通过释放它不再需要存储或返回一个错误。
的malloc()尝试其最佳分配内存。 如果失败,而不是重新尝试在while循环分配内存(程序可能会被卡住永远存在),试图释放一些其他进程或线程持有一些内存,如果你能,然后重试。
另一种方法是增加存储器,通过增加交换文件或寻呼存储器,在飞行中,从代码本身(但它的危险和不优选的)或手动操作的方式它内。
为了避免这样的问题,最好的方法是计算或估计对内存的需求,一边写代码本身。
尝试增加堆大小(存储器用于动态分配的预留)。