如何正确使用malloc和free memory?

时间:2014-07-04 13:30:22

标签: c++ c memory malloc free

我想知道使用malloc和free的正确/标准方式是什么。是否需要在释放后设置指针NULL?基本上,以下两种方式中的哪一种是正确的?

double* myPtr = (double*)malloc(sizeof(double)*5);
.....
free(myPtr);

double* myPtr = (double*)malloc(sizeof(double)*5);
.....
free(myPtr);
myPtr = NULL;

或者它应该是使用malloc和free的其他方法吗?感谢。

7 个答案:

答案 0 :(得分:10)

两者都很好。唯一的区别是,如果您尝试第二次释放myPtr,前一种方法会崩溃。

根据您使用的语言,malloc行可以稍微整理一下。

使用sizeof(*myPtr)在以后重构时不太容易出错。如果你正在使用C,那么演员也是不必要的

double* myPtr = malloc(sizeof(*myPtr)*5);

正如WhozCraig所指出的,如果你正在使用C ++,那么有更简单的方法来分配数组

 std::vector<double> ar(5);

为您提供5个double的数组,如果需要,它将增加其存储空间,并在超出范围时自动释放其内存。

答案 1 :(得分:7)

没有必要在语句

中将指针设置为NULL
myPtr = NULL;

一方面,如果您尝试第二次释放指针,这可以防止程序执行错误。另一方面,它可能隐藏了第二次尝试释放指针的错误代码。

因此,是否需要将指针设置为NULL取决于程序设计。

如果您正在谈论C ++,那么如果您使用永远不会使用C函数malloc和free会更好。考虑使用智能指针,例如std :: shared_ptr。

答案 2 :(得分:3)

将指针设置回&#34; NULL&#34;只有在你以后需要再次使用它并对其进行检查时才会有用,例如&#34; if(myPtr){[...]}&#34;。如果你不打算重复使用这个特定的指针,你可以把它留给他的价值。

答案 3 :(得分:2)

你写的是正确的(但是在C中你不应该转换malloc的返回值,但在C ++中你必须进行转换)。 调用myPtr后,您不必将free设置为NULL。如果已被释放,请不要取消引用内存。

答案 4 :(得分:2)

您可以自由地使用指针。你不必将它设置为NULL,但如果你不想免费获得SEGFAULT,它会很好。

让我们看看例子。

double * ptr = malloc(sizeof(double) * 42 );
ptr[0] = 1.2; // OK
free (ptr); // OK
ptr = malloc(sizeof(double) * 13); // It's OK. You don't need to set pointer to NULL

让我们看一些更多的例子。

void assign(ptr)
{
    if( ptr != NULL) ptr[0] = 1.2;
}

double * ptr = NULL;
assign(ptr); // All OK, method will not pass check
double * ptr = malloc(sizeof(double) * 42);
assign(ptr); // OK, method will pass check and assign
free(ptr);
// ptr = NULL; // If we don't do this ....
.... a lot of code and 666 lines below ... 
assign(ptr); // BAH! Segfault! And if You assign ptr=NULL, it would not a segfault

答案 5 :(得分:1)

Use of free

  

free()仅将内存块标记为空闲 - 没有强制执行此释放操作。 对于初学者和有经验的程序员来说,访问以前释放的内存块是造成许多内存错误的原因。一个好的做法是始终使刚刚释放的指针无效。

如果是C,只需删除演员:

double* myPtr = malloc(sizeof(double)*5);
.....
free(myPtr);
myPtr = NULL; 

答案 6 :(得分:1)

如果可以避免,最好避免使用malloc/free。如果

,你可以避免它
  • 您要分配的数组或结构是&#34;小&#34; (您可以计算手指的大小),并且您知道编译时的大小

  • 在程序的本地范围内使用和丢弃数组

如果这些都是真的,请不要使用malloc/free,而只使用从堆栈而不是堆中分配的本地自动变量。

例如,这更简单,更易于维护

 {
   double myPtr[5];
   ...
 }

比这个

 {
   double* myPtr = (double*)malloc(sizeof(double)*5);
   ...
   free(myPtr);
 }

在可能的情况下使用堆栈变量是一种很好的做法,因为堆栈永远不会得到碎片&#34;像堆一样可以。但是当然,堆栈可能会溢出,所以不要放任何东西&#34; big&#34;在堆栈上。知道什么是&#34;大&#34;不是一门精确的科学;你应该事先知道你的堆栈大小。