我正在开发一个使用Win32的HeapAlloc的通用库
MSDN没有提到Win32的HeapAlloc的对齐保证,但我真的需要知道它使用的对齐方式,所以我可以避免过多的填充.
在我的机器上(vista,x86),所有分配都以8个字节对齐.这对其他平台也是如此吗?
哪些是用于查看实现堆分配器的不同方式的优缺点的一些好资源?涉及效率(碎片,吞吐量等)的资源是首选.我不是在寻找简单的代码库.
编辑:
我对这个wiki的哲学基础并不感兴趣.因此,我真的不想进入'为什么'我对此感兴趣.无论潜在的意图/问题/等,这些信息都存在,所以如果你知道任何好的资源,请在这里链接到他们!
我有代码,由于各种原因,我正在尝试从C运行时移植到使用Windows Heap API的代码.我遇到了一个问题:如果我重定向malloc/ calloc/ realloc/ free调用HeapAlloc/ HeapReAlloc/ HeapFree(使用GetProcessHeap的手柄),内存似乎是正确分配(无不良指针返回,没有抛出异常),但我的图书馆porting因某种原因说"未能分配内存".
我已尝试使用Microsoft CRT(使用下面的Heap API)和另一个公司的运行时库(使用下面的Global Memory API); 两者的malloc适用于库,但由于某些原因,直接使用Heap API不起作用.
我已经检查过分配不是太大(> = 0x7FFF8字节),而它们不是.
我能想到的唯一问题是内存对齐; 那是这样吗?或者除此之外,Heap API和我不知道的CRT内存API有根本区别吗?
如果是这样,它是什么?如果没有,那么为什么静态 Microsoft CRT(包含在Visual Studio中)在调用之前malloc/ calloc之前需要一些额外的步骤HeapAlloc?我怀疑存在差异,但我想不出它可能是什么.
谢谢!
所以我一直在考虑PIMPL和堆栈分配.我一直在写一个库,并决定使用PIMPL隐藏该类的私有成员.这意味着我会有一个像这样声明的类
class Foo {
private:
class Handle;
std::tr1::shared_ptr<Handle> handle;
public:
Foo();
};
Run Code Online (Sandbox Code Playgroud)
这很直接.但是然后在构造函数中你这样做
Foo::Foo() : handle(new Handle()) {}
Run Code Online (Sandbox Code Playgroud)
因此,当使用我的库的人在堆栈上创建Foo时,他们实际上是在进行堆分配.这是使用PIMPL时必须要考虑的权衡吗?我想在构造函数旁边发出警告释放文档:"警告:这会导致堆分配"或者其他一些问题.
我的另一个想法是将所有暴露给实现的类作为纯虚拟接口和一大堆静态工厂方法返回智能指针.这也意味着堆分配,但没有技巧.
有什么想法或建议吗?我是否过度考虑使用我的图书馆的程序员?
我想知道在Windows C编程中推荐哪种方法:使用malloc或Win32 HeapAlloc(可能是VirtualAlloc?)函数.
我已经阅读了有关malloc和HeapAlloc 的MSDN 内存管理函数文章和MSDN文章,但是他们没有说明应该使用哪一个以及在什么情况下.
它似乎没有意义,除非我们只是忽略一个段开头的任何潜在的多余空间,然后让第一个分配的块位于8的第一个倍数(其对应的第一个头是该地址-4) .这将在未使用之前留下许多字节.这是普遍做的吗?
编辑: 感谢paxdiablo的详细说明如下.这对16字节标题都有意义.但是,我正在使用一个4字节的标题,看起来像这样:
struct mhdr {
int size; // size of this block
} tMallocHdr;
Run Code Online (Sandbox Code Playgroud)
现在,如果我的堆开始的地址是8的倍数,并且malloc返回的任何地址需要是8的倍数,并且我需要使用4个字节的标题,我似乎被迫"浪费"第一个我的堆的4个字节.例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
^
(heap starts)
Run Code Online (Sandbox Code Playgroud)
如果堆在地址8处的胡萝卜上面开始,使用本例中的寻址方案,我可以在malloc调用之后返回给用户的第一个可返回地址为16; 我需要4个字节的标头,第一个地址是8的倍数,它允许4个字节的标题是16(标题从12开始).这意味着我浪费了内部堆内存的前4个字节来排队(8-11).
这是可以接受的牺牲,还是我在考虑这个错误?
我正在做一个关于动态内存管理的项目。我对 HeapCreate 和 HeapAlloc 函数感到困惑。
对于 HeapCreate() 函数,我们可以创建一个堆,该函数将返回一个 HANDLE。我们可以初始化堆的大小。
假设 winHandle = HeapCreate( 0, 2 * 1024, 0);
然后,我可以使用 HeapAlloc 函数在这个堆上进行分配。但我对堆的大小感到困惑。我试了一个例子,我在这个堆上调用 HeapAlloc(winHandle, 0, 1024) 两次,所以总数是 2 * 1024。但是我仍然可以多次调用 HeapAlloc 而不会遇到错误。
假设我调用了 HeapAlloc( winHandle, 0, 1024) 三次。分配的总大小将为 3 * 1024。它大于堆大小 2 * 1024。但没有错误。
谁能帮我回答这个问题?
谢谢,
这里是测试代码。
// create heap, and return a headle(id) for that heap
HANDLE winHandle = HeapCreate( 0, sizeof(Dog), sizeof(Dog) );
// allocate the heap header to that handle
void* s = HeapAlloc( winHandle, 0, sizeof(Dog) );
// …Run Code Online (Sandbox Code Playgroud) heapalloc ×7
c ×4
c++ ×3
malloc ×2
alignment ×1
heap ×1
heap-memory ×1
msvcrt ×1
performance ×1
pimpl-idiom ×1
stackalloc ×1
virtualalloc ×1
winapi ×1
windows ×1