如果已知 void* 分配大小,如何将确切的内存大小传递给 free()

Posted

技术标签:

【中文标题】如果已知 void* 分配大小,如何将确切的内存大小传递给 free()【英文标题】:How to pass exact memory size to free() if void* allocation size is known 【发布时间】:2015-03-09 02:02:50 【问题描述】:

据我所知;在c++和c中delete操作符或free()函数可以通过pionter数据类型知道分配内存的大小,delete可以自动调用析构函数。

如果分配的指针是使用一种在其机制中不使用新运算符的单例静态动态数组注册的(即仅malloc) 在超载的新指针中。此数组注册void* 指针并从重载的new operator 中获取该指针的大小

例如。

void * operator new (size_t sz) 
  void * m = malloc (sz);
  Dynamic_Array::get_instance()->add(m,sz) ; //registering  pointer
  return m ;

所以我的问题是如何使用有关大小的信息来释放我忘记使用该数组的析构函数删除的确切分配的内存。

例如

Dynamic_Array::~Dynamic_Array() 
  int index = 0;
  while(index < storage_size) //storage_size: total number of pointers in array 

 /* storage is void** array which  register 
   allocated pointers as void* and use classic memset and memcpy to enlarge*/

    
      if (storage[index] != NULL) printf("Pointer : %d was not deleted\n", storage[index]);
//how to use delete or free here to delete void* pointer  but with known size of memory
      index ++;
      

谢谢。

【问题讨论】:

你不需要知道大小。如果它是使用 malloc 分配的,则可以使用 free 释放它。内存管理器知道它分配的块有多大。 但是如果我说 free(void*) free 是否确切地知道分配内存的大小?如果我通过强制转换将 C++ 对象 * 指针传递给 void * 我怎么能调用 delete (void*) “因为它会发出删除未知类型 (void*) 的警告” 我的意思是如何赋予数组该指针的所有权 你不能调用delete(void*).它不存在。你不需要。你打电话给free(). 不..他不能使用 free 因为它可能会泄漏,因为 free 不会调用析构函数。他将他的类指针转换为void*,并想知道如何删除在该内存地址分配的类。 【参考方案1】:

据我所知;在c++和c中,删除操作符或者free()函数可以从pionter数据类型知道分配内存的大小

没有。删除操作符调用free()函数; free() 函数以某种方式从与指针关联的元数据中知道大小,例如内存中前一个字中的长度字。

而del​​ete可以自动调用析构函数。

是的。

我的问题是如何使用有关大小的信息来释放我忘记使用该数组的析构函数删除的确切分配内存。

你不需要知道。见上文。

【讨论】:

"... the free() function knows the size from metadata associated with the pointer somehow ..." 你能详细说明一下吗?或者给个参考? 这里有一个相关问题:***.com/questions/1518711/…【参考方案2】:

在 C 中,

free() 函数使用围绕已分配内存的堆中的数据结构。

该数据结构包括已分配内存的实际起始地址、堆中前一个内存块的地址以及堆中下一个内存块的地址。

一般来说,堆实际上是两个链表。

一个是分配内存,一个是空闲内存。

malloc 操作从空闲链表中获取适当大小的块并将其放入分配的内存链表中。 这可能涉及将一个较大的空闲内存块分成两个较小的内存块,其中一个被移动到分配的内存链表中,并且指针在空闲内存列表中为新块调整

一个空闲的从分配的内存链表中删除该条目并将其放入空闲链表中。

那么如果空闲链表包含两个相邻的内存块,那么这两个内存块被组合成一个/更大的内存块。

有几种算法可用于准确确定哪个空闲区域被分解/移动到分配的内存列表。

【讨论】:

你的最后一段没有什么意义。与malloc 返回地址相比,new 返回地址有何不同或“棘手”。 C++ 也不做垃圾收集,所以我不知道最后一句话想说什么。 C++ 在尝试分配大于任何当前可用块但小于当前可用块总和的内存块时,可以合并相邻的内存块。但是,由于它只是可用的算法之一,我会很好地删除最后一段 是的,堆管理器可以合并相邻的空闲块,但是当您使用“垃圾收集”或“移动内存位置”之类的短语时,它会产生误导。它使 C++ 内存管理听起来有点像 Java。

以上是关于如果已知 void* 分配大小,如何将确切的内存大小传递给 free()的主要内容,如果未能解决你的问题,请参考以下文章

分配适当的内存大小

将内存和存储分配到指针中

动态分配内存-realloc

堆上分配的内存大小

为什么我们不能在堆栈上分配动态内存?

Visual Studio 2010 C++:获取 malloc 分配的内存块大小