代码之家  ›  专栏  ›  技术社区  ›  Fayeure

为什么我们需要检查C中的MalOC返回值,而不是C++中的新值?[副本]

  •  -1
  • Fayeure  · 技术社区  · 4 年前

    在C++中有一件我不懂的事情。相反,在C中,当我们调用 malloc 我们检查分配是否失败,然后释放之前分配的所有内存,以便在没有内存泄漏的情况下进行干净的退出。

    new 操作人员我知道它会抛 std::bad_alloc 失败时,但如果以前成功分配了 在抛出异常时,我们会留下内存泄漏,不是吗?

    int main(void) {
        int *ptr1 = new int;
        int *ptr2 = new int;
    
        // do something with ptrs
        delete ptr1;
        delete ptr2;
        return (EXIT_SUCCESS);
    }
    

    而在C中,我们会这样做

    #include <stdlib.h>
    
    int main(void) {
        void *ptr1;
        void *ptr2;
    
        if (!(ptr1 = malloc(10)))
            return (EXIT_FAILURE);
    
        if (!(ptr2 = malloc(10))) {
            free(ptr1);
            return (EXIT_FAILURE);
        }
        //do something with ptrs
        free(ptr1);
        free(ptr2);
        return (EXIT_SUCCESS);
    }
    

    标准:坏的

    #include <new>
    
    int main(void) {
        int *ptr1 = new int;
        int *ptr2;
    
        try {
            ptr2 = new int;
        } catch (std::bad_alloc &e) {
            // do something with exception
            delete ptr1;
            return (EXIT_FAILURE);
        }
        // do something with ptrs
        delete ptr1;
        delete ptr2;
        return (EXIT_SUCCESS);
    }
    
    0 回复  |  直到 4 年前
        1
  •  4
  •   Useless    4 年前

    但是在C++中,似乎没有人关心新操作符。我知道它会在失败时抛出std::bad_alloc,但如果以前使用new成功分配了内存,那么在抛出异常时就会出现内存泄漏,不是吗?

    例如:

    {
        int *ptr1 = new int;
        int *ptr2 = new int;
        // do something with ptrs
        delete ptr1;
        delete ptr2;
    }
    

    这是一种糟糕的风格。没有信誉良好的推荐人会建议你写这封信。

    不,下面是 坏(虽然它更像是用C++编写的java,而不是用C++编写的C)

    {
        int *ptr1 = new int;
        int *ptr2;
    
        try {
            ptr2 = new int;
        } catch (std::bad_alloc &e) {
             delete ptr1;
             return;
        }
        // do something with ptrs
        delete ptr1;
        delete ptr2;
    }
    

    通常的建议(例如,根据 Core Guidelines )它们是:

    1. (当然,我们会假设你只是在简化一些确实需要的东西 new / delete

    2. 如果必须有动态分配,请使用RAII,并且永远不要拥有原始指针

      因此,原始代码的正确版本是

      {
          auto ptr1 = std::make_unique<int>();
          auto ptr2 = std::make_unique<int>();
          // do something with ptrs
      }
      

      这实际上不那么复杂,而且是完全正确的。

        2
  •  1
  •   HackerDev-Felix    4 年前

    Neal/Delphi是一个C++运算符,MalC/C++是一个C/C++标准库函数

    malloc/free仅动态分配内存空间/释放空间,而new/delete除了分配空间外还调用构造函数和析构函数来初始化和清理(清理成员)

    malloc/free需要手工计算类型大小,返回值为void*,new/delete可以自行计算类型大小并返回相应的类型指针

    malloc/free失败并返回0,new/delete失败并引发异常。