如何正确使用malloc和free memory?

时间:2021-10-12 21:19:08

I am wondering what is the right/standard way to use malloc and free. Is it needed to set pointer NULL after free? Basically, which of the two following ways is correct?

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

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

or

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

Or it should be other ways to use malloc and free? Thanks.

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

7 个解决方案

#1


10  

Both are fine. The only difference is that the former approach would crash if you tried to free myPtr a second time.

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

Depending on the language you're using, the malloc line could be tidied up a little.

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

Using sizeof(*myPtr) is less prone to bugs when you later refactor. If you're using C, the cast is also unnecessary

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

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

As pointed out by WhozCraig, if you're using C++, there are much easier ways to allocate an array

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

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

gives you an array of 5 doubles that will grow its storage if required and automatically free its memory when it goes out of scope.

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

#2


7  

There is no any need to set the pointer to NULL in statement

没有必要在语句中将指针设置为NULL

myPtr = NULL;

On the one hand this prevents the program from an execution error if you will try to free the pointer the second time. On the other hand it maybe hides the bug code where you try to free the pointer the second time.

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

So whether you need to set the pointer to NULL depends on the program design.

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

If you are speaking about C++ then it would be better if you would use never C functions malloc and free. Consider using of smart pointers as for example std::shared_ptr.

如果你正在谈论C ++,那么如果你使用永远不会使用C函数malloc并且免费的话会更好。考虑使用智能指针,例如std :: shared_ptr。

#3


3  

Setting the pointer back to "NULL" will only be useful if you need to reuse it again later and run checks on it like "if(myPtr) { [...] }". If you don't plan on reusing this specific pointer, you can leave it to whatever his value is.

将指针设置回“NULL”仅在以后需要重新使用它并对其运行检查时才有用,例如“if(myPtr){[...]}”。如果您不打算重复使用此特定指针,则可以将其保留为其值。

#4


2  

You are free to do with Your pointer anything. You don't MUST set it to NULL, but it's good if You don't want to get SEGFAULT for free.

您可以随意使用指针。你不必将它设置为NULL,但如果你不想免费获得SEGFAULT,这是很好的。

Let see examples.

让我们看看例子。

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

Let see some more examples.

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

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


2  

What you write is correct (however in C you shouldn't cast the return value of malloc, but in C++ you must do the cast). You don't have to set myPtr to NULL after calling free. Just don't dereference the memory after if has been freed.

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

#6


1  

Use of free:

使用免费:

free() only marks the memory chunk as free - there is no enforcement of this freeing operation. Accessing memory chunks that were previously freed is the cause of many memory errors for novices and experienced programmers. A good practice is that always nullify a pointer that was just freed.

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

In case of C, just remove the cast:

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

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

#7


1  

It is best to avoid malloc/free if you can avoid it. You can avoid it if

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

  • the array or structure you are allocating is "small" (you can count the size on your fingers) and you know the size at compile time

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

  • the array is used and discarded in the local scope of your program

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

If these are true, don't use malloc/free, but just use local auto variables which are allocated from the stack instead of the heap.

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

For example, this is simpler and easier to maintain

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

 {
   double myPtr[5];
   ...
 }

than this

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

It's good practice to use stack variables when you can, because a stack never gets "fragmented" like a heap can. But of course, a stack can overflow, so don't put anything "big" on the stack. Knowing what is "big" is not an exact science; you should know what your stack size is beforehand.

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

#1


10  

Both are fine. The only difference is that the former approach would crash if you tried to free myPtr a second time.

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

Depending on the language you're using, the malloc line could be tidied up a little.

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

Using sizeof(*myPtr) is less prone to bugs when you later refactor. If you're using C, the cast is also unnecessary

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

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

As pointed out by WhozCraig, if you're using C++, there are much easier ways to allocate an array

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

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

gives you an array of 5 doubles that will grow its storage if required and automatically free its memory when it goes out of scope.

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

#2


7  

There is no any need to set the pointer to NULL in statement

没有必要在语句中将指针设置为NULL

myPtr = NULL;

On the one hand this prevents the program from an execution error if you will try to free the pointer the second time. On the other hand it maybe hides the bug code where you try to free the pointer the second time.

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

So whether you need to set the pointer to NULL depends on the program design.

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

If you are speaking about C++ then it would be better if you would use never C functions malloc and free. Consider using of smart pointers as for example std::shared_ptr.

如果你正在谈论C ++,那么如果你使用永远不会使用C函数malloc并且免费的话会更好。考虑使用智能指针,例如std :: shared_ptr。

#3


3  

Setting the pointer back to "NULL" will only be useful if you need to reuse it again later and run checks on it like "if(myPtr) { [...] }". If you don't plan on reusing this specific pointer, you can leave it to whatever his value is.

将指针设置回“NULL”仅在以后需要重新使用它并对其运行检查时才有用,例如“if(myPtr){[...]}”。如果您不打算重复使用此特定指针,则可以将其保留为其值。

#4


2  

You are free to do with Your pointer anything. You don't MUST set it to NULL, but it's good if You don't want to get SEGFAULT for free.

您可以随意使用指针。你不必将它设置为NULL,但如果你不想免费获得SEGFAULT,这是很好的。

Let see examples.

让我们看看例子。

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

Let see some more examples.

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

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


2  

What you write is correct (however in C you shouldn't cast the return value of malloc, but in C++ you must do the cast). You don't have to set myPtr to NULL after calling free. Just don't dereference the memory after if has been freed.

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

#6


1  

Use of free:

使用免费:

free() only marks the memory chunk as free - there is no enforcement of this freeing operation. Accessing memory chunks that were previously freed is the cause of many memory errors for novices and experienced programmers. A good practice is that always nullify a pointer that was just freed.

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

In case of C, just remove the cast:

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

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

#7


1  

It is best to avoid malloc/free if you can avoid it. You can avoid it if

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

  • the array or structure you are allocating is "small" (you can count the size on your fingers) and you know the size at compile time

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

  • the array is used and discarded in the local scope of your program

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

If these are true, don't use malloc/free, but just use local auto variables which are allocated from the stack instead of the heap.

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

For example, this is simpler and easier to maintain

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

 {
   double myPtr[5];
   ...
 }

than this

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

It's good practice to use stack variables when you can, because a stack never gets "fragmented" like a heap can. But of course, a stack can overflow, so don't put anything "big" on the stack. Knowing what is "big" is not an exact science; you should know what your stack size is beforehand.

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