C++中的内存分配
Memory allocate in c++
我有一个项目,在我的程序启动时我必须分配 1024 个字节。在 C++ 程序中。
void* available = new char*[1024];
我写了这个,我觉得还可以。
现在我的问题开始了,我应该创建一个函数来接收我应该分配的 size_t 大小(字节数)。我的分配应该 return 一个指向可用内存的第一个字节的 void* 指针。所以我的问题是如何分配具有大小的 void* 指针并从我的可用内存中获取内存。
我是一名学生,不是 C++ 专业人士。
也很抱歉我的解释不当。
您似乎在尝试制作 memory pool。尽管这是一个很大的话题,但让我们看看您可以付出最少的努力来创建这样的东西。
游泳池有一些基本要素需要掌握。首先是内存本身,即你从哪里提取内存。在您的情况下,您已经决定要动态分配固定数量的内存。要正确执行此操作,代码应为:
char *poolMemory = new char[1024];
这里没有选择void* pool
,因为delete[] pool
是undefined when pool is a void pointer。您可以使用 malloc/free
,但我会保留它 C++。其次,我没有像您的代码所示那样分配指针数组,因为它分配了 1024 * sizeof(char*)
字节的内存。
第二个考虑因素是如何归还您为池获取的内存。在你的情况下,你要记住删除它,所以最好将它放在 class 中为你做 RAII:
class Pool
{
char *_memory;
void *_pool;
size_t _size;
public:
Pool(size_t poolSize = 1024)
: _memory(new char[poolSize])
, _pool(_memory)
, _size(poolSize)
{
}
~Pool() { delete[] _memory; } // Forgetting this will leak memory.
};
现在我们来谈谈您要问的部分。你想在那个池中使用内存。在 Pool
class 中创建一个名为 allocate
的方法,它将返回 n 个字节。此方法应该知道池中还剩下多少字节(成员 _size
),并且实质上执行指针运算以让您知道哪个位置是空闲的。不幸的是有陷阱。您必须提供生成的内存应具有的所需对齐方式。这是另一个大话题,从我不认为你打算处理的问题来看(所以我默认对齐为 2^0=1 字节)。
#include <memory>
void* Pool::allocate(size_t nBytes, size_t alignment = 1)
{
if (std::align(alignment, nBytes, _pool, _size))
{
void *result = _pool;
// Bookkeeping
_pool = (char*)_pool + nBytes; // Advance the pointer to available memory.
_size -= nBytes; // Update the available space.
return result;
}
return nullptr;
}
我用 std::align
做了这个指针运算,但我想你可以手工完成。在现实世界的场景中,您还需要一个 deallocate
函数,该函数在使用后“打开”池中的点。当池 运行 内存不足时,您还需要一些策略,即后备分配。此外,初始内存获取可以更有效,例如通过在适当的地方使用静态内存。这有很多风格和方面,我希望我最初包含的 link 能给你一些动力来研究这个主题。
我有一个项目,在我的程序启动时我必须分配 1024 个字节。在 C++ 程序中。
void* available = new char*[1024];
我写了这个,我觉得还可以。 现在我的问题开始了,我应该创建一个函数来接收我应该分配的 size_t 大小(字节数)。我的分配应该 return 一个指向可用内存的第一个字节的 void* 指针。所以我的问题是如何分配具有大小的 void* 指针并从我的可用内存中获取内存。
我是一名学生,不是 C++ 专业人士。 也很抱歉我的解释不当。
您似乎在尝试制作 memory pool。尽管这是一个很大的话题,但让我们看看您可以付出最少的努力来创建这样的东西。
游泳池有一些基本要素需要掌握。首先是内存本身,即你从哪里提取内存。在您的情况下,您已经决定要动态分配固定数量的内存。要正确执行此操作,代码应为:
char *poolMemory = new char[1024];
这里没有选择void* pool
,因为delete[] pool
是undefined when pool is a void pointer。您可以使用 malloc/free
,但我会保留它 C++。其次,我没有像您的代码所示那样分配指针数组,因为它分配了 1024 * sizeof(char*)
字节的内存。
第二个考虑因素是如何归还您为池获取的内存。在你的情况下,你要记住删除它,所以最好将它放在 class 中为你做 RAII:
class Pool
{
char *_memory;
void *_pool;
size_t _size;
public:
Pool(size_t poolSize = 1024)
: _memory(new char[poolSize])
, _pool(_memory)
, _size(poolSize)
{
}
~Pool() { delete[] _memory; } // Forgetting this will leak memory.
};
现在我们来谈谈您要问的部分。你想在那个池中使用内存。在 Pool
class 中创建一个名为 allocate
的方法,它将返回 n 个字节。此方法应该知道池中还剩下多少字节(成员 _size
),并且实质上执行指针运算以让您知道哪个位置是空闲的。不幸的是有陷阱。您必须提供生成的内存应具有的所需对齐方式。这是另一个大话题,从我不认为你打算处理的问题来看(所以我默认对齐为 2^0=1 字节)。
#include <memory>
void* Pool::allocate(size_t nBytes, size_t alignment = 1)
{
if (std::align(alignment, nBytes, _pool, _size))
{
void *result = _pool;
// Bookkeeping
_pool = (char*)_pool + nBytes; // Advance the pointer to available memory.
_size -= nBytes; // Update the available space.
return result;
}
return nullptr;
}
我用 std::align
做了这个指针运算,但我想你可以手工完成。在现实世界的场景中,您还需要一个 deallocate
函数,该函数在使用后“打开”池中的点。当池 运行 内存不足时,您还需要一些策略,即后备分配。此外,初始内存获取可以更有效,例如通过在适当的地方使用静态内存。这有很多风格和方面,我希望我最初包含的 link 能给你一些动力来研究这个主题。