C++ 释放确切大小的内存

C++ Deallocate exact size of memory

本文关键字:内存 释放 C++      更新时间:2023-10-16

我已经考虑过如何提高读取按(无符号(整数排序的列表的性能,该整数在程序启动时读入,在程序退出之前不会更改。我想过不同的可能性,但后来我有一个想法,我想知道这是否可能,如果不是,为什么不呢 - 因为在我的理论中,计算机应该是可能的。

我有一个包含 10.000 个条目的列表,每个条目都有一个唯一的 ID(唯一 ID 不是 0(。现在如何分配大小为 object* pList = new(sizeof(object) * max_unique_id) 的内存,然后删除所有未使用的内存(检查不存在的唯一 id 并在大小为 sizeof(object(的位置释放内存(...您将只使用所需的内存,并且只需访问带有pList[unique_id]的列表条目 -> 将非常非常快......但您不能删除动态分配数组中的单个元素:/在程序终止时,您当然可以释放所有元素,在 std::vector 或 sth 中保护指针 + 大小是没有问题的。

这就是为什么我要问我的理论是不正确的,还是系统不允许它,或者问题出在哪里。

不,你不能那样控制内存。 但是,有可能作弊一点。 如果要分配大块内存,则可以创建自己的内存池。 这样,您可以自己创建孔并将该内存用于程序的其他部分。

不过,我不建议这样做,因为您可能会遇到严格的别名问题,并且必须处理代码中的更多复杂性。

稍微倒回一点,您就会忘记缓存效果,这很重要。 与加快查找速度相比,将对象紧密打包在一起可能会对速度产生更大的影响。

为了实现这一点,你可以使用一个简单的哈希来查找你的对象,或者你可以只创建一个16位索引的稀疏索引数组。

你可以,(虽然我不知道你为什么要这样做(,但你必须把它写成你自己的自定义内存分配和释放例程或类。 使用开箱即用的标准C++库,您不能。

查看一些用于在C++中分配内存的接口

void* operator new  ( std::size_t );
void* operator new[]( std::size_t );
void* operator new  ( std::size_t, const std::nothrow_t&);
void* operator new[]( std::size_t, const std::nothrow_t&);

void* operator new[]( std::size_t );为例。此例程绝对无法知道将返回的内存区域中存储了多少对象。

与它的匹配功能相同

 void operator delete[]( void* ptr );

它只需要一个void指针,它绝对无法知道您要删除多少。提供内存的内存分配器从ptr指向的块开始,神奇地知道它分配的大小,因此适当地删除它

使用 placement new .

<小时 />
object* pList = new(sizeof(object) * max_unique_id)

不要这样做。 new不是malloc.但你也不能这样做:

object* pList = new object[max_unique_id];
delete object[1];

C++ 不允许使用简单的delete删除单独分配的数组的元素。

C++允许您使用 placement new 在预先分配的内存空间中创建对象。在这种情况下,必须通过调用放置 new 和析构函数来手动调用构造函数。

参考:Malloc 和构造函数

A* a = (A*)malloc(sizeof(A));
new (a) A();
a->~A();
free(a);

换句话说,提供要创建特定对象的确切位置。我建议你使用一个循环:

// Allocate the space using malloc()
object* pList = std::malloc(sizeof(object) * max_unique_id);
// Allocate using a loop. I would not trust a parallelization of this code.
// Doing memory allocation in parallel without the proper locks and stuff
// is probably wrong.
for (auto i = 0; i < max_unique_id; ++i) {
  // Supply the point as the argument to placement new.
  new (&pList[i]) object(/* arguments go here */);
}

然后,当您使用完某个对象时,说i = 20...

// Select the object
object* todelete_object = pList[i];
// Manually call the destructor.
todelete_object->~object()
// Now, free the memory.
std::free(todelete_object);

我使用std::malloc()std::free()如C++式C标准库包含。