C和C++的内存管理有什么区别

What are the differences between memory management in C and C++

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

更广泛地说,C 和 C++ 处理内存管理的方式有何不同?例如,我在 C 中需要注意哪些事情可能有人在 C++ 中没有考虑到?

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

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 returns a void* 但它与其他指针类型兼容。

在 C 和 C++ 中你需要自己管理内存,但是 C 没有像 unique_ptr 这样的东西——而且,没有 newdelete,使用 mallocfree。还有 callocrealloc.

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

按照要求,在释放数组时,你基本上只是反过来做同样的事情。注意 free 不接受大小,只接受指针。 free 函数会忽略 NULL 指针,所以你在这里不必担心。

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

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

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

因此,在析构函数中 运行 动态内存取消分配是一个很好的做法,以确保当实例不再在范围内时释放实例分配的任何动态内存。

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

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

malloc 要求您检查 return 值是否为 NULL 以检查它是否失败,而 new 将在野外抛出 std::bad_alloc 异常失败。

另一个很大的区别是 C++ 有内存泄漏运算符 new[],它分配的数组会在再次意外使用 delete 而不是 delete[] 时发生泄漏。

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

C++ 中的手动内存分配通常是不受欢迎的,这是有充分理由的。在这种情况下,您宁愿使用 std::string 而让 class 担心内存分配。或者,您可以使用智能指针 class 为您进行重新分配。