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
这样的东西——而且,没有 new
和 delete
,使用 malloc
和 free
。还有 calloc
和 realloc
.
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 中。
malloc
和 new
之间的主要区别在于 new
将调用分配对象的默认构造函数(如果适用)。这就是为什么在 C++ 中混合这两者是非常糟糕的做法的原因之一。
malloc
要求您检查 return 值是否为 NULL 以检查它是否失败,而 new
将在野外抛出 std::bad_alloc
异常失败。
另一个很大的区别是 C++ 有内存泄漏运算符 new[]
,它分配的数组会在再次意外使用 delete
而不是 delete[]
时发生泄漏。
C++ 还允许您重载这些运算符 - 存在您需要这样做的有效案例,但大多数情况下这是非常值得怀疑的做法。
C++ 中的手动内存分配通常是不受欢迎的,这是有充分理由的。在这种情况下,您宁愿使用 std::string
而让 class 担心内存分配。或者,您可以使用智能指针 class 为您进行重新分配。
如何为 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
这样的东西——而且,没有 new
和 delete
,使用 malloc
和 free
。还有 calloc
和 realloc
.
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 中。
malloc
和 new
之间的主要区别在于 new
将调用分配对象的默认构造函数(如果适用)。这就是为什么在 C++ 中混合这两者是非常糟糕的做法的原因之一。
malloc
要求您检查 return 值是否为 NULL 以检查它是否失败,而 new
将在野外抛出 std::bad_alloc
异常失败。
另一个很大的区别是 C++ 有内存泄漏运算符 new[]
,它分配的数组会在再次意外使用 delete
而不是 delete[]
时发生泄漏。
C++ 还允许您重载这些运算符 - 存在您需要这样做的有效案例,但大多数情况下这是非常值得怀疑的做法。
C++ 中的手动内存分配通常是不受欢迎的,这是有充分理由的。在这种情况下,您宁愿使用 std::string
而让 class 担心内存分配。或者,您可以使用智能指针 class 为您进行重新分配。