【问题标题】:Allocating more than what you need and freeing the extra space分配比您需要的更多的空间并释放额外的空间
【发布时间】:2021-12-09 14:29:22
【问题描述】:

我想知道是否有可能过度分配并释放您分配的多余部分?我在想一些类似的事情

/*
This is a pseudo program, just to show what I am talking about, there should be more
checks to prevent overflow.
*/
typedef struct {
  struct Node *neighbor
  int value
} Node;

...
Node create_tree(char* content, int size) {
  int mem_index = 0
  Node *last_node;
  // size > sizeof(Node)
  void base* = malloc(size);
  while( mem_index < size) {
    Node nptr* = (Node)(base + mem_index);
    if(last_node != NULL) nptr->neighbor = last_node;
    last_node = nptr;
    mem_index += sizeof(Node);
    nptr->value = (int)(base + mem_index)
    (nptr->value)* = get_some_content(content);
    mem_index += sizeof(int);   
  }
  free((base + mem_index));
} 

基本上,这个程序过度分配并开始将内存转换为结构,然后写入这些结构。它将结构内的指针指向内存中的其他点。然后,它在完成写入的所有单元之后写入另一个结构。我想知道这是否可行,如果可行,这是一种好的做法吗?我听说分配不足是一个问题,如果我要动态创建它们,我不喜欢每次想要创建新结构时都进行分配。

【问题讨论】:

  • 我不喜欢每次创建新结构时都进行分配”。这通常是比你拥有的更好的方法。除非您需要非常小心地管理内存,例如专门的嵌入式系统,否则让标准库分配器管理所有这些可能会更好。它将使您的代码更简单、更易于理解且不易出错。
  • 但是不,你不能free只是内存的一部分。您需要分配一个新的较小块,将所有数据从较大块复制到较小块,然后将free 复制到较大块。幸运的是,有一个标准函数可以为您做到这一点 - realloc
  • 注意:void base* = malloc(size); ... base + mem_index 不是可移植代码。使用标准 C,无法添加到 void *
  • 您只能将地址传递给free(),该地址是从malloc() 等获得的。确切的地址,而不是分配中的某个位置。
  • int 类型不是最适合跟踪相对内存偏移的。 ptrdiff_t 似乎更合适。还要非常注意内存对齐。

标签: c malloc free


【解决方案1】:

您可以使用 realloc 将内存块缩小到所需的大小:

base2 = realloc(base, mem_index);

如果调用成功,则base + mem_index之后的内存将被释放。

顺便说一句。使用 void* 类型的指针进行算术是 GCC 扩展。你应该使用char*

请注意,返回的base2 可能与原始base 不同。您使用 base2 更新所有对 base 的现有引用。

【讨论】:

  • 不完全正确。可能会释放整个块,并在另一部分内存中分配另一个较小的块。
  • @WeatherVane,是的,我在最后添加了一个适当的注释。
猜你喜欢
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 2016-11-30
  • 2018-11-24
  • 2020-04-16
  • 1970-01-01
  • 2020-10-29
  • 1970-01-01
相关资源
最近更新 更多