我有以下C函数:
void mySwap(void * p1, void * p2, int elementSize)
{
void * temp = (void*) malloc(elementSize);
assert(temp != NULL);
memcpy(temp, p1, elementSize);
memcpy(p1, p2, elementSize);
memcpy(p2, temp, elementSize);
free(temp);
}
我想在通用排序功能中使用。假设我使用它来对main()拥有的动态分配的数组进行排序。现在让我们假设在某些时候mySwap()中的temp实际上是NULL并且整个程序被中止而不释放main()中动态分配的数组。我认为mySwap()和排序函数都可以返回一个bool值来指示分配是否成功,并且通过使用if语句我可以释放main()中的数组并退出(EXIT_FAILURE),但它似乎不是像一个非常优雅的溶剂。在这种情况下防止内存泄漏的好方法是什么?
答案 0 :(得分:3)
assert
通常在调试期间用于识别不应发生的问题/错误。
内存不足是可能发生的事情,因此不应由assert
处理,或者,如果您使用assert
,请注意它将中止程序。一旦程序中止,程序使用的所有内存都将被释放,因此不必担心。
注意:如果您不想在任何地方使用笨拙的if
语句来处理几乎不会发生的错误,您可以使用setjmp/longjmp
返回可恢复状态。
答案 1 :(得分:1)
您必须意识到malloc失败的原因是因为您的计算机内存不足。从那时起,你的程序没有任何意义,除了尽可能优雅地终止。
操作系统将在程序终止时释放内存,因此这不是您需要担心的事情。
不过,在正常情况下,手动free()
自己是个好习惯。不是为了“让内存再次可用” - 操作系统将确保 - 但要验证您的程序在整个过程中没有出现严重错误并创建堆损坏,泄漏或其他错误。如果您的程序中有这样的错误,它会在free()
调用期间崩溃,这是一件好事,因为错误会浮出水面。
assert
最好不要在生产代码中使用。如果需要,建立自己的错误处理,这比在执行过程中暴力终止自己的程序更好。
答案 2 :(得分:1)
不使用malloc
来避免此问题。
不是为每个交换分配一块内存,而是一次交换一个字节;
for (int i = 0; i < elementSize; ++i) {
char tmp = ((char*)p1)[i];
((char*)p1)[i] = ((char*)p2)[i];
((char*)p2)[i] = tmp;
}
答案 3 :(得分:0)
仅在开发期间使用assert()
来捕获程序员错误,在发布版本中它不会执行任何操作。如果您需要测试其他内容,请使用正确的错误处理,无论这意味着abort()
,还是代码还是使用setjmp()
/ longjmp()
模拟异常。