我有以下问题:
如果我在方法中使用malloc
,return
指向我的main
的指针,并在我的 main 中free
指针,我是否成功释放了内存?如果我这样做,这是糟糕的编程风格吗?
int* mallocTest(int size)
{
int * array = (int*) malloc(size);
return array;
}
int main ()
{
int* pArray = mallocTest(5);
free (pArray);
return 0;
}
编辑:这个问题的主要目的是我想知道,当我将其拆分为方法和主要函数时,如果我成功释放了内存(如果我使用malloc-free/new[]-delete[]的正确"组合"!
编辑2:更改了代码和主题,以引导问题的预期要点
混合malloc
释放它与delete
在其他答案中解释。
我觉得你想知道malloc
方法中分配的内存,将指针返回到main
,并且 main 中的指针free
是否有效?是的,可以完成,free
将清除在其他方法中分配的内存,前提是您有指向该位置的指针。
No.使用free
释放分配了malloc
的内存,delete
在数组上使用new
时,使用new
和delete []
分配单个对象。
混合和匹配可能看起来有效(这是未定义的行为,"未定义"包括"工作正常"和"大部分时间工作正常,但在几个月中的星期四崩溃,从 M 开始,在可与 3 或 7 整除的日子里,操作员有带条纹的衬衫") - 并且可能确实适用于某些类型的系统, 但在其他方面失败,这取决于malloc
和new
及其各自的free
和delete
功能的实现方式。
可以调用一个函数,该函数返回指向某个内存的指针,该内存稍后通过适当的调用释放。如果你实际实现一对函数,其中一个分配,另一个销毁数据,那就"更好"了。如果分配的数据结构不是微不足道的(例如,您在外部分配中有分配),这一点尤其重要。
还要考虑如果您决定"哦,我想在mallocTest()
中使用new int[size];
而不是malloc(size * sizeof(int));
"会发生什么。现在,每个调用mallocTest()
的地方都必须进行更改,以便它调用delete []
而不是您在阅读此答案后将其更正为free
。
[刚刚发现你的代码坏了,可能不会编译,当然不会分配空间:(int *)malloc[size];
没有做你想让它做的事情,我很确定是非法的,因为索引函数是无效的]
最后,"最佳"解决方案是将所有分配包装在一个对象中,以便该对象的析构函数销毁对象内分配的数据。因此,例如,使用std::vector<int>
而不是使用malloc
分配。
不 - 这是未定义的 bahaviour,这意味着它可能看起来有效,但实际上它不起作用,malloc()
您应该始终使用free()
.仅将delete[]
用于分配了new[]
的内存。
您实际上可以自己检查它,new[]
调用void* operator new(size_t)
方法,该方法应该在您的平台标头中声明。最简单的方法是监视它使用调试器所做的工作,在VS2005下,它会在最终调用HeapAlloc
函数。
对于释放,您有void operator delete[](void*)
也必须在 somwhere 中定义。在VS2005上,它调用HeapFree
。
我检查了哪些malloc/免费电话,这些电话也是HeapAlloc
和HeapFree
。
所以就我而言,它看起来会起作用,因为malloc
看起来它的实现方式与new[]
相同。但关键是这里没有魔力,new[]
应该与delete[]
配对,malloc()
与free()
配对,因为你永远不知道这些是如何在给定平台上实现的。
- 当您使用malloc或new动态分配内存时,您 为特定目的"保留"堆内存的一部分。 内存将保持"保留"状态,直到您将其返回到堆中 使用">释放">或"删除"(取决于用于分配的内容)。
- 话虽如此,您可以从程序中的任何位置分配内存,并从任何地方*分配内存。 然而,重要的是要确定并做 如果您忘记释放分配的内存,则会出现内存泄漏
实际上,你应该将free
与malloc
一起使用,delete
与new
一起使用,但对我来说,这不是因为未定义,它可能会爆炸核弹,调用鼻魔或其他什么。(或者简单地说,维护噩梦)malloc
和new
根本不做同样的事情。为了简化实际上有点复杂的事情:
- 继承自 C 的
malloc
分配了一大块内存。时期。 new T
分配一个大小正确的内存块,用于存储类型为T
的对象(可能通过malloc
),并执行该对象的构造函数。
相反:
delete ptr
执行ptr
指向的对象的析构函数,并释放相关的内存块。free(ptr)
释放内存块。时期。
为了使宇宙不分崩离析,对构造函数的每个调用都必须与对析构函数的调用匹配。这是语言的保证。(也是C++最大的优势之一)
这就是为什么每次调用malloc
都必须与对free
的调用相匹配,因为free
是为了撤消malloc
所做的。对new
的每个调用都必须与对delete
的调用相匹配,因为delete
是为了撤消new
所做的操作。