【问题标题】:C how to free sub memory?C如何释放子内存?
【发布时间】:2018-11-13 18:53:26
【问题描述】:

我分配了一个大内存 char* test= malloc(10000000); ,然后我将值放在这个内存上,并为每个值做一些工作。

我想要的是,每1000个索引,我想释放所有内存,直到它为止。

例如

for(long i=0; i<10000000;i++)
   DoSomeWork(test[i]);
   if(i%1000==0)
       releaseMemory(i-1000,i);

如何在 c 中做到这一点?

我知道free 只能释放我所有分配的内存,但我不想等到工作结束才释放所有内存。

我希望每 1000 部作品免费全部 1000 部回来

我必须在程序开始时分配所有内存。

【问题讨论】:

  • 如果您预先分配内存,您认为在循环内“释放”它意味着什么?您认为需要定期撤消的 DoSomeWork() 函数内部发生了什么?
  • 你需要为你想要的写你自己的内存分配器。以相反的顺序工作,并在需要时致电brk() 和朋友。
  • 有几种方法可以做到这一点。一种是在系统级别继续分配一个大块,但使用您自己的机制来控制您的 对象中的哪一个可以使用您的 内存的哪一位。例如,您可能有一个标志数组,指示在任何给定时间哪些内存块正在使用。另一种方法是将您的分配分成更小的部分,并在适当的时候释放它们(并可能重新分配它们)。

标签: c memory malloc free


【解决方案1】:

你想要的可以通过将程序分配成更小的块来实现。

你必须调整你的算法来处理一堆小的子数组,然后你可以在使用后释放它们。

在这种情况下,反向分配块以使 libc 有机会将释放的内存释放到底层操作系统可能会很有用。

让我在这里加强一点:

假设您想要一个包含 10000000(1000 万)个条目的数组。而不是像问题中描述的那样将其分配为一个块,而是可以有

#define CHUNKSIZE 10000
#define ENTRYSIZE 8
#define NUM_CHUNKS 1000

void test(void)
{
    void** outer_array = malloc(NUM_CHUNKS * sizeof(void*))
    for (int i = 0; i < NUM_CHUNKS; i++) {
        void * chunk = malloc(CHUNKSIZE * ENTRYSIZE);
        outer_array[NUM_CHUNKS - 1 - i] = chunk;
        // allocate them in reverse order
    }

    // now, set item #123456
    size_t item_index = 123456;
    // TODO check if the index is below the maximum
    size_t chunk_index = item_index / CHUNKSIZE;
    size_t index_into_chunk = item_index % CHUNKSIZE;
    void * item_address = &outer_array[chunk_index][index_into_chunk * ENTRY_SIZE];

    // after having processed one chunk, you can free it:
    free(outer_array[0]);
    outer_array[0] = NULL;
}

程序如何增强堆以分配内存(大致)有两种可能性:

  1. 它可以从操作系统获得一个全新的内存块,独立于“主地址空间”。然后它可以使用它进行分配,并在它为free()d 时立即将其返回给操作系统。如果分配大小超过某个阈值,则在某些分配器中会发生这种情况。
  2. 它可以增强程序地址空间。然后,最后添加新内存。在free()ing最后一个内存块之后,程序地址空间可以再次减少。如果分配大小低于某个阈值,则在某些分配器中会发生这种情况。

这样,您的程序的内存占用会随着时间的推移而减少。

【讨论】:

  • 也可以使用更小的realloc。不过,不确定它是否能释放很多
  • 另外请记住,仅仅因为您 free 内存并不一定意味着它会立即(甚至很快)可供操作系统使用。
  • @Jean-FrançoisFabre 我也这么认为,但realloc 的问题是它从结束中解放出来,而不是开始。而他想要的是从一开始。
  • 您可以将数组反向计算 1000 个块。但是,它很丑陋,有很多添加、子和索引魔法。 eeek
猜你喜欢
  • 2020-09-10
  • 2015-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 2011-01-31
相关资源
最近更新 更多