6

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

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

或者

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

或者应该是其他方式使用malloc和free?谢谢。

4

7 回答 7

12

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

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

以后重构时使用sizeof(*myPtr)不太容易出现错误。如果您使用 C,也不需要强制转换

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

正如 WhozCraig 所指出的,如果您使用的是 C++,则有更简单的方法来分配数组

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

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

于 2014-07-04T13:33:02.660 回答
7

无需在语句中将指针设置为 NULL

myPtr = NULL;

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

所以是否需要将指针设置为NULL取决于程序设计。

如果您谈论的是 C++,那么最好不要使用 C 函数 malloc 和 free。考虑使用智能指针,例如 std::shared_ptr。

于 2014-07-04T13:37:31.720 回答
3

仅当您需要稍后再次重用它并像“if(myPtr) { [...] }”一样对其进行检查时,将指针设置回“NULL”才有用。如果您不打算重用此特定指针,则可以将其保留为他的值。

于 2014-07-04T13:32:37.563 回答
2

用途free

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

在 C 的情况下,只需删除演员表:

double* myPtr = malloc(sizeof(double)*5);
.....
free(myPtr);
myPtr = NULL; 
于 2014-07-04T13:32:35.600 回答
2

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

于 2014-07-04T13:33:00.280 回答
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
于 2014-07-04T13:35:54.383 回答
1

malloc/free如果可以避免,最好避免。你可以避免它,如果

  • 您分配的数组或结构是“小”(您可以数出手指的大小)并且您知道编译时的大小

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

如果这些是真的,不要使用malloc/free,而只是使用从堆栈而不是堆分配的局部自动变量。

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

 {
   double myPtr[5];
   ...
 }

比这个

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

尽可能使用堆栈变量是一种很好的做法,因为堆栈永远不会像堆一样被“碎片化”。但是当然,堆栈可能会溢出,所以不要在堆栈上放任何“大”的东西。知道什么是“大”并不是一门精确的科学。你应该事先知道你的堆栈大小。

于 2014-07-07T20:36:11.547 回答