【问题标题】:What are the differences between memory management in C and C++C和C++中的内存管理有什么区别
【发布时间】:2020-04-04 04:47:29
【问题描述】:

如何为const char*s 的数组动态分配内存?即,例如const char** array = /* ??? */。我知道malloc 类似于 C++ 中的new,但总是返回一个void*

更广泛地说,在 C 和 C++ 中处理内存管理的方式有什么区别?例如,在 C 语言中我必须注意哪些在 C++ 中可能不会有人考虑的事情?

【问题讨论】:

  • C和C++在内存管理上的区别在于C++假装有一些。 :-)
  • 在 C++ 中 std::vector<const char *> v(N); 。虽然首先使用 const char * 会很糟糕
  • 作为@M.M 刚才所说的证据,请考虑在几天前将this issued I opened 替换为pulseaudio(修复为here)。

标签: c++ c memory memory-management heap-memory


【解决方案1】:

mallocnew 之间的主要区别在于new 将调用分配对象的默认构造函数(如果适用)。这就是为什么在 C++ 中混合这两者是非常糟糕的做法的原因之一。

malloc 要求您检查 NULL 的返回值以检查它是否失败,而 new 将在失败时抛出一个 std::bad_alloc 异常。

另一个很大的不同是,C++ 有内存泄漏运算符new[],它分配一个数组,当人们再次意外使用delete 而不是delete[] 时,该数组将会泄漏。

C++ 还允许您重载这些运算符 - 存在您需要这样做的有效情况,但大多数情况下这是非常值得怀疑的做法。

出于充分的理由,C++ 中的手动内存分配大多不受欢迎。在这种情况下,您宁愿使用 std::string 并让该类担心内存分配。或者,您可以使用智能指针类为您进行释放。

【讨论】:

    【解决方案2】:

    C++ 中存在但 C 中没有的另一个内存管理方面是 C++ 对类具有面向对象的方法。当一个实例被创建时,该实例的构造函数被调用,当该实例超出范围时,析构函数被调用,此行为由编译器自动执行,并且对程序员是透明的。

    因此,最好在析构函数中运行动态内存解除分配,以确保当实例不再在范围内时释放实例分配的任何动态内存。

    构造函数和析构函数的概念只存在于 C++ 中,而不存在于 C 中。

    【讨论】:

    • 对于那些不熟悉这个概念的人来说,这就是所谓的RAII(我知道,这个名字没有帮助)。
    • “在析构函数中运行动态内存解除分配是一种很好的做法”,不仅如此。 “三法则”。
    【解决方案3】:

    要分配数组,你可以这样做:

    const char **array = malloc( x * sizeof( char * ) );
    

    然后分配数组的每个元素。

    if ( array )
        for ( int i = 0; i < x; ++i )
            array[i] = malloc( y * sizeof( char ) );
    else
        printf( "malloc failed :(" );
    

    malloc 返回一个void*,但它与其他指针类型兼容。

    在 C 和 C++ 中,您需要自己管理内存,但 C 没有 unique_ptr 之类的东西——此外,没有 newdelete,使用 mallocfree。还有callocrealloc

    malloc 可以在失败的情况下返回NULL,所以你应该也检查一下。请注意,它不会像 C++ 中的 new 那样抛出。有关malloc 的更多信息,请访问here

    根据要求,在释放数组时,您基本上只是反向执行相同的操作。注意free 不接受大小,只接受指针。 free 函数将忽略 NULL 指针,因此您不必在这里担心。

    for ( int i = 0; i < x; ++i )
       free( array[i] );
    free( array );
    

    当然,就像在 C++ 中一样,不要加倍 free 内存。那很不好。 :)

    【讨论】:

    • C 也没有像 std::vectorstd::map 这样可以为你做很多内存管理的便利。
    • 非常感谢您的回答;它写得很好而且直截了当。有没有什么方法可以包含解除分配过程?
    • @DrakeJohnson 添加了。
    • 你为什么检查第一个malloc的结果而不是后面的?
    • @M.M.,没有特别的原因。只是一个例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 2010-09-09
    • 2021-11-10
    相关资源
    最近更新 更多