C++,新与 malloc return 值

C++, new vs malloc return value

当我学习C99时被告知要始终检查malloc的return值来检查它是成功还是失败,但现在我开始了学习 C++ 我被告知没有必要用关键字 new 来做这件事,你可以假设它总是对你有用。

但这是为什么呢?

有很多方法可以检查 return 值,

  • 如果你使用 nothrow 版本,你可以检查 returned 指针
  • 您可以在更高级别上使用 try 块
  • 您可以使用 set_new_handler 检查所有新的句柄。

我更喜欢第二个和第三个

New 分配内存并调用构造函数进行对象初始化:如果失败则抛出异常 std::bad_allocmalloc 分配内存但不调用构造函数:如果它的分配失败,它 return 一个 null 指针,所以你必须检查你从中得到了什么。 但是,在 C++ 中,您不能假设 new 将始终有效:您可以假设如果它不起作用,它会抛出异常。

new 仍然会失败并抛出 std::bad_alloc 异常,您的程序 需要 可能会检查它是否失败,或者只是让异常传播向上。还有一个标志,您可以传递给 new,使其在出错时表现得像 malloc 和 return NULL。看看 documentation.


编辑 这里有两个例子:

try {
  char* arr = new char[20];
} catch (std::bad_alloc& e) {
  // Handle error
}

或者使用 nothrow 标志,使 new 表现得像 malloc:

char* arr = new (std::nothrow) char[20];
if (!arr) {
  // Handle error
}

任何动态分配都可能失败。

malloc 通过 returning NULL 发出信号。如果它失败了,除非你明确检查它的 return 程序将继续,即使 malloc 失败,当你尝试通过指针 return 访问时很可能导致未定义的行为 malloc (这是无效的)。这就是为什么您应该始终检查 malloc 失败。

另一方面,

new 通过抛出 std::bad_alloc 异常(默认行为)来发出信号。如果您没有捕获异常,它将冒泡到顶部并终止您的程序。这是需要的,因此您无需执行任何操作。


另请注意,在 C++ 中,您永远不应显式调用 new/delete。使用标准容器,如 std::vector 或智能指针。

在C++中,除非使用高级特性,否则如果new运算符无法分配内存,则会抛出异常,因此无需检查[=11=获得的指针是否存在] 是否为空。处理异常取决于程序员。如果不这样做,程序将突然终止。正确处理此异常并在没有内存或资源泄漏的情况下重新启动操作实际上很棘手,这就是为什么现在认为使用 newdelete 分配对象已过时。使用容器和智能指针是更好的选择。

请注意,您可以在 malloc():

上使用包装器在 C 中获得相同的行为
#include <stdio.h>
#include <stdlib.h>

void *xmalloc(size_t size) {
    void *p = malloc(size);
    if (p == NULL) {
        fprintf(stderr, "malloc failed for %zu bytes\n", size);
        exit(1);
    }
    return p;
}

不需要xmalloc()检查内存分配失败,因为这样的失败会导致程序自动突然终止。这种方法可用于失败不是灾难性的并且可以交互处理的命令行实用程序。