我想知道使用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的其他方法吗?感谢。
答案 0 :(得分:10)
两者都很好。唯一的区别是,如果您尝试第二次释放myPtr
,前一种方法会崩溃。
根据您使用的语言,malloc
行可以稍微整理一下。
使用sizeof(*myPtr)
在以后重构时不太容易出错。如果你正在使用C,那么演员也是不必要的
double* myPtr = malloc(sizeof(*myPtr)*5);
正如WhozCraig所指出的,如果你正在使用C ++,那么有更简单的方法来分配数组
std::vector<double> ar(5);
为您提供5个double
的数组,如果需要,它将增加其存储空间,并在超出范围时自动释放其内存。
答案 1 :(得分:7)
没有必要在语句
中将指针设置为NULLmyPtr = 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)
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;不是一门精确的科学;你应该事先知道你的堆栈大小。