每次迭代我需要为临时数组分配一次空间。我尝试在每次迭代中使用realloc来优化内存使用。比如:
int *a = (int*)std::alloc(2 * sizeof(int));
for(int i=0; i<N; ++i)
{
int m = calculate_enough_size();
a = (int*)std::realloc(m * sizeof(int));
// ...
}
std::free(a);
N
是一个很大的数字,例如1000000。每个迭代有示例m
值:8,2,6,10,4,8
当我在每次迭代中重新分配a
时,我做得对吗?它是否防止冗余内存分配?
首先,realloc
取2个参数。第一个是原始指针,第二个是新的大小。您正试图将大小作为原始指针进行传递,而代码不应进行编译。
其次,必须提醒:不要过早优化。除非您已经测量并发现分配是一个瓶颈,否则只需使用std::vector
。
我注意到的几个问题是:
-
Realloc应该在您希望旧值保留在内存中的情况下使用,如果您没有像您的一条评论中提到的那样关心旧值,请使用alloc。
-
在再次分配之前,请检查已分配内存的大小,如果分配的内存不足以容纳新数据,则只分配新内存。
请参阅将处理上述问题的示例代码:
int size = 2;
int *a = (int*)std::alloc(size * sizeof(int));
for(int i=0; i<N; ++i)
{
int m = calculate_enough_size();
if(m > size)
{
size = m;
std::free(a);
a = (int*)std::alloc(size * sizeof(int));
}
// ...
}
std::free(a);
此外,您还可以通过分配一些额外的内存来进一步优化内存分配,例如:
size = m*2; //!
为了更好地理解这一步骤,让我们举一个例子,假设m=8,那么您将分配内存=16。因此,当现在m更改为10、12到16时,无需再次分配内存。
如果您可以提前获得所有大小,请在循环之前分配所需的最大大小,然后根据需要使用。
另一方面,如果你不能做到这一点,那么我认为重新分配是一个很好的解决方案。
您还可以通过只在需要更大的规模时重新分配来进一步优化您的解决方案:
int size = 0;
for(int i = 0; i < N; ++i)
{
int new_size = calculate_enough_size();
if ( new_size > size ){
a = (int*)std::realloc(new_size * sizeof(int));
size = new_size;
}
// ...
}
像这样,您将需要更少的重新分配(其中一半在随机情况下)。