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

问题描述 投票:0回答:4

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

c malloc assert abort
4个回答
3
投票

assert通常在调试期间用于识别不应发生的问题/错误。

内存不足是可能发生的事情,所以要么不应该由assert处理,要么如果你使用assert,请注意它将中止程序。一旦程序中止,程序使用的所有内存都将被释放,因此不必担心。

注意:如果您不想在任何地方使用笨拙的if语句来处理几乎不会发生的错误,您可以使用setjmp/longjmp返回可恢复状态。


1
投票

您必须意识到malloc失败的原因是因为您的计算机内存不足。从那时起,除了尽可能优雅地终止之外,你的程序没有任何意义。

操作系统将在程序终止时释放内存,因此您无需担心这些问题。

尽管如此,在正常情况下,free()手动当然是好的做法。不是为了“让内存再次可用” - 操作系统将确保 - 但要验证您的程序在整个过程中没有出现严重错误并创建堆损坏,泄漏或其他错误。如果你的程序中有这样的bug,它会在free()调用期间崩溃,这是一件好事,因为bug会浮出水面。

assert最好不要用在生产代码中。如果需要,建立自己的错误处理,这比在执行过程中暴力终止自己的程序更好。


1
投票

不使用malloc避免这个问题。

不是为每个交换分配一块内存,而是一次交换一个字节;

for (int i = 0; i < elementSize; ++i) {
  char tmp = ((char*)p1)[i];
  ((char*)p1)[i] = ((char*)p2)[i];
  ((char*)p2)[i] = tmp;
}

0
投票

只在开发期间使用assert()来捕获程序员错误,在发布版本中它不会做任何事情。如果您需要测试其他内容,请使用正确的错误处理,无论是abort(),返回代码还是使用setjmp() / longjmp()模拟异常。

顺便说一句,do not cast the result of malloc()

© www.soinside.com 2019 - 2024. All rights reserved.