简体   繁体   English

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

[英]C++ Deallocate exact size of memory

I've thought about how I can improve the performance of reading of a list sort by an (unsigned) integer that is read in at the program start and won't change until the program exits. 我已经考虑过如何通过在程序启动时读取的(无符号)整数来提高列表排序的读取性能,并且直到程序退出时才改变。 I thought about different possibilities but then I got an idea and I'd like to know if that's possible and if not, why not - because in my theory it should be possible for the computer. 我考虑了不同的可能性,但后来我有了一个主意,我想知道这是否可能,如果不能,为什么不可以-因为从我的理论来看,计算机应该是可能的。

I have a list with something like 10.000 entries, every entry has an unique ID (an the unique ID is not 0). 我有一个包含10.000个条目的列表,每个条目都有一个唯一的ID(唯一的ID不为0)。 Now what about allocating memory with the size object* pList = new(sizeof(object) * max_unique_id) and then deleting all the unused memory (check what unique id is not existing and free the memory at the position with the size sizeof(object))... you would be using only the needed memory and you could just access to a list entry with pList[unique_id] -> would be really, really fast... but you cannot delete a single element in a dynamic allocated array :/ At the program termination you can of course free all the elements, it's no problem to safe the pointer + sizes in a std::vector or sth like that. 现在如何以大小为object* pList = new(sizeof(object) * max_unique_id)分配内存,然后删除所有未使用的内存(检查不存在唯一的ID,并在大小为sizeof(object)的位置释放内存)...您将只使用所需的内存,并且可以使用pList[unique_id] ->来访问列表条目,这确实非常快...但是您不能删除动态分配数组中的单个元素: /当然,在程序终止时,您可以释放所有元素,将指针+大小安全地保存在std :: vector或sth中是没有问题的。

That's why I'm asking if my theory is incorrect or if the system just does not allow it or where the problem is. 这就是为什么我要问我的理论是否错误,或者系统是否不允许它或者问题出在哪里。

No, you can't control memory like that. 不,您不能那样控制内存。 However, it IS possible to cheat a little bit. 然而,也可以骗一点点。 If you are allocating big chunks of memory, you can make your own memory pool. 如果要分配大块内存,则可以创建自己的内存池。 That way, you can create the holes yourself and use that memory for other parts of your program. 这样,您可以自己创建漏洞并将该内存用于程序的其他部分。

I wouldn't recommend it though, as you may have issues with strict aliasing , as well as having to deal with more complexity in your code. 不过,我不建议您这样做,因为您可能会遇到严格的别名问题,并且不得不处理代码中的更多复杂性。

Rewinding just a little, you are forgetting about caching effects, which are significant. 快退几下,您会忘记重要的缓存效果。 Keeping your objects packed closely together will likely have more effect on speed than making the lookup faster. 与快速查找相比,将对象紧密排列在一起可能会对速度产生更大的影响。

To achieve this you could use a simple hash to look up your objects, or you could just make a sparse index array of 16-bit indices. 为此,您可以使用简单的哈希查找对象,也可以仅制作16位索引的稀疏索引数组。

You can, (though I have no idea why you want to), but you will have to write it as your own custom memory allocation and deallocation routine or class. 您可以(尽管我不知道为什么要这么做),但是您必须将其编写为自己的自定义内存分配和释放例程或类。 Using the standard C++ library out of the box, you can't. 不能使用现成的标准C ++库。

See some of the interfaces for allocating memory in 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&);

Taking void* operator new[]( std::size_t ); 使用void* operator new[]( std::size_t ); for example. 例如。 There is absolutely no way the this routine knows how many objects are stored in the memory region that will be returned. 此例程绝对不可能知道将返回的内存区域中存储了多少个对象。

Same with it's matching function 与它的匹配功能相同

 void operator delete[]( void* ptr );

it only takes a void pointer, there is absolutely no way it knows how many you want to delete. 它只需要一个void指针,绝对不可能知道您要删除多少个指针。 The memory allocator that provided memory starting with that block pointed by ptr magically knows the size it allocated, and hence deletes it appropriately ptr指向的那个块开始提供内存的内存分配器神奇地知道了它分配的大小,因此可以适当地删除它

Use placement new . 使用placement new


object* pList = new(sizeof(object) * max_unique_id)

Do not do this. 不要这样做。 new is NOT malloc . new的不是malloc But you also cannot do this instead: 但是您也不能这样做:

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

C++ does not allow to delete individually allocated elements of a dyanmically allocated array with a simple delete . C ++不允许使用简单的delete动态分配的数组中各个分配的元素。

C++ allows you to create an object in a pre-allocated memory space by using placement new . C ++允许您通过使用placement new在预分配的内存空间中创建对象。 In this case, you must manually call the constructor with a call to placement new and the destructor. 在这种情况下,您必须手动调用构造函数,并同时调用new和destructor放置。

Reference: Malloc and constructors 参考: Malloc和构造函数

A* a = (A*)malloc(sizeof(A));
new (a) A();

a->~A();
free(a);

In other words, supply the exact place where you want a specific object to be created. 换句话说,提供您想要创建特定对象的确切位置。 I would suggest that you use a loop: 我建议您使用循环:

// 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 */);
}

Then, when you're done using a certain object, say i = 20 ... 然后,使用完某个对象后,说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);

I use std::malloc() and std::free() as defined in the C++-style C standard library includes. 我使用C ++风格的C标准库包括的std::malloc()std::free()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM