当你在main中动态分配内存时,如何处理函数中的assert()?

时间:2018-03-01 13:36:22

标签: c malloc assert abort

我有以下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),但它似乎不是像一个非常优雅的溶剂。在这种情况下防止内存泄漏的好方法是什么?

4 个答案:

答案 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()模拟异常。

另外,do not cast the result of malloc()