让我们假设我有此代码:
for (int i=0;i<n;i++) {
//compute z
float *p = (float *) malloc (sizeof(float)*z);
//do something with p
}
请注意,p
在其他任何地方都没有使用,并且每个for
周期都独立于另一个。
让我们假设z
不是那么大,因此单> p
在MEMMORY方面并不昂贵。但是,n
可能很大,因此p
所获得的总内存可以保持一致。
free()
与:
for (int i=0;i<n;i++) {
//compute z
float *p = (float *) malloc (sizeof(float)*z);
//do something with p
free(p);
}
奖励问题:如果时间性能是优先级(而不是内存消耗),则最好避免使用free(p)
,因为它很耗时?
由于您用 c 标记了此标签,因此切勿使用malloc
和free
。使用智能指针(或new
/delete
,如果您无法访问C 11-符合编译器)。
for (int i=0;i<n;i++) {
// compute z
std::unique_ptr<float[]> p{new float[z]};
// do something with p
// p gets automatically freed at the end of the scope
}
回答您的问题:
用...
释放()是正确的()
是。如果您将某些内容分配给malloc
,则始终需要free
。
最好避免免费(P),因为它很耗时?
是。考虑将循环外的内存位置进行预先关注。
// preallocate
std::unique_ptr<float[]> p{new float[z]};
for (int i=0;i<n;i++) {
// clear p
// compute z
// do something with p
}
// p gets automatically freed at the end of the scope
您可以在周期之前预先分配必要的内存量并重新使用。
如果您不知道z
有多大 - 我建议在某个地方写入分配的内存的大小,如果z
比它大 - 然后重新分配,否则 - 只是重新使用已分配的内存。
观察:使用malloc
。ACT:调用free
。就这么简单。便携式,定义明确的代码需要malloc
和 free
。
分配的内存量在这里没有作用。如果内存太多,malloc
会丢失错误,但这与您始终需要free
遵循malloc
的事实无关。
是。您必须free
。否则,您会有内存泄漏,这很糟糕。特别是如果您循环大量次数。
一个好的经验法则是,每个malloc
都必须由free
匹配。总是。(这在较大的项目中尤其重要)
考虑使用缓冲区,以避免不必要的分配。可以通过使用std::vector<float>
很容易地完成此操作:
std::vector<float> p;
for (int i=0;i<n;i++) {
//compute z
p.resize( z );
//do something with p
}
在最坏的情况下,您将获得O(log n)
内存分配。使用您的代码,您将获得n
内存分配。不调用free()
只是导致内存泄漏。std::vector<float>
最终将自动清理内存。
看起来大小是恒定的,那么为什么要一次又一次地分配它?只需在循环之前分配一次,在开头的循环初始化内。您可以重复使用内存。循环结束后,自由记忆。
且程序在循环后结束,然后您不必释放它,所有消耗程序的堆存储器都将返回到操作系统,但是释放您分配的内存始终是一个好习惯。在奖励问题上,自由不是耗时,而是分配记忆,因此请不要担心免费的时间。
如果再次重用该内存 - 显然,只有在结束程序并仅分配一次时,才能更有效地释放它(并且在需要更大/较小的阵列时使用realloc()
进行重新分配)。
您可能会编程的每个操作系统都将在程序终止时动态分配的内存。但是,由于我们大多尝试将代码保持尽可能的跨平台,因此您应始终free()
动态分配的内存。
至于您只有大量的记忆和关心速度 - 那么显然free()
ING会"减慢"程序,但是它花费的时间是如此荒谬的时间很小,76*(10**-8)
在我的不起眼的机器上,因为1024个字节块,因此相当微不足道。