【问题标题】:Can I use std::realloc to prevent redundant memory allocation?我可以使用 std::realloc 来防止冗余内存分配吗?
【发布时间】:2014-09-12 11:17:12
【问题描述】:

每次迭代我都需要为一个临时数组分配一次空间。我尝试使用 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 时,我做得对吗?是否防止冗余内存分配?

【问题讨论】:

  • 是否需要跨迭代维护数组的内容?
  • 你可以通过迭代保存当前的 a 大小,只有在需要更多大小时才重新分配
  • 没有。 'a' 在每个 realloc 之后填充 'm' 新值
  • 一次性分配你需要的最大尺寸。然后在每次迭代中将值重置为默认值,然后根据需要使用它。
  • @user743414 在迭代之前不可能得到最大的'm'值

标签: c++ memory-management realloc


【解决方案1】:

首先,realloc 有 2 个参数。第一个是原始指针,第二个是新大小。您正在尝试将大小作为原始指针传递,并且代码不应编译。

其次,强制提醒:不要过早优化。除非您测量并发现分配是瓶颈,否则请使用std::vector

【讨论】:

    【解决方案2】:

    我注意到的几个问题是:

    • 如果您希望旧值保留在内存中,则应使用 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 无需再次分配内存。

    【讨论】:

      【解决方案3】:

      如果你能事先得到所有的尺寸,在循环之前分配你需要的最大的,然后根据需要使用。

      另一方面,如果你不能这样做,那么我认为重新分配是一个很好的解决方案。

      您还可以通过仅在需要更大尺寸时重新分配来进一步优化您的解决方案:

      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;
          }
      
          // ...
      }
      

      这样,您将需要更少的重新分配(其中一半在随机情况下)。

      【讨论】:

      • 迭代前不可能得到最大的'm'值
      • “仅在需要更大尺寸时重新分配”。为什么每次迭代都比重新分配更好?
      • @user1312837 因为你需要更少的重新分配。
      • Realloc 可能会将您的旧数据移动到新位置,也就是复制,但您不需要重复使用旧数据。所以少用 realloc 更好
      猜你喜欢
      • 2017-01-11
      • 2019-11-16
      • 2018-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-10
      • 2016-07-04
      • 2015-05-22
      相关资源
      最近更新 更多