LocalAlloc和LocalRealloc用法

时间:2010-05-06 20:31:51

标签: c++ memory windows-mobile

我有一个Visual Studio 2008 C ++ Windows Mobile 6应用程序,我正在使用FindFirst()/ FindNext()样式API来获取项目集合。我不知道提前列表中有多少项目。所以,我想为这些项动态分配一个数组。

通常情况下,我会使用std::vector<>,但由于其他原因,这不是此应用程序的选项。所以,我正在使用LocalAlloc()LocalReAlloc()

我不清楚的是这个记忆是否应该标记为固定或可移动。应用程序运行正常。我只是想知道什么是“正确的”。

int count = 0;
INFO_STRUCT* info = ( INFO_STRUCT* )LocalAlloc( LHND, sizeof( INFO_STRUCT ) );
while( S_OK == GetInfo( &info[ count ] )
{
    ++count;
    info = ( INFO_STRUCT* )LocalRealloc( info, sizeof( INFO_STRUCT ) * ( count + 1 ), LHND );
}

if( count > 0 )
{
    // use the data in some interesting way...
}

LocalFree( info );

谢谢, PaulH


编辑:响应者(不是不合理地)使用LocalAlloc()而不是其他更好的选项。所以我会提供更多背景信息。

这个代码块正在从RAPI可调用DLL中执行。因此,在这种情况下,它看起来更像是这样:

FOO_API int RapiInvokable_Foo( DWORD /*cbInput*/, 
                               BYTE* /*pInput*/,
                               DWORD* pcbOutput, 
                               BYTE** ppOutput,
                               IRAPIStream* /*pStream*/ )
{
    int count = 0;
    INFO_STRUCT* info = ( INFO_STRUCT* )LocalAlloc( LPTR, sizeof( INFO_STRUCT ) );
    while( S_OK == GetInfo( &info[ count ] )
    {
        ++count;
        info = ( INFO_STRUCT* )LocalRealloc( info, sizeof( INFO_STRUCT ) * ( count + 1 ), LHND );
    }

    *ppOutput = ( BYTE* )info;
    *pcbOutput = sizeof( INFO_STRUCT ) * ( count + 1 );
    return S_OK;
}

来自CeRapiInvoke()文档:

应用程序应使用LocalAlloc函数为pInput参数分配内存。调用者负责释放pInput。系统为ppOutput参数分配内存。当应用程序使用缓冲区完成时,应该使用LocalFree函数释放内存。

3 个答案:

答案 0 :(得分:2)

根据MSDN,使用本地功能没有任何好处:http://msdn.microsoft.com/en-us/library/aa366723(VS.85).aspx。为什么不使用常规malloc和free或new并删除。他们可能是你最好的选择。

答案 1 :(得分:2)

从您链接的页面到您对miked的回复的评论

“在线性Windows Embedded CE API环境中,本地堆和全局堆之间没有区别.LocalAlloc等同于HeapAlloc(GetProcessHeap,...)。”

点击链接去查看CE 6.0(或Win Mobile 6.0),你会看到同样的事情。

事实上,neww / malloc等内部所有内容都是内部的HeapAlloc。所以我真的不确定使用C / C ++运行时的问题是什么......

编辑:

从这个Dr Dobbs链接中可以看出:

  

在中使用LocalAlloc和LocalReAlloc   这种方式暴露了一个怪癖   Windows CE实现。在里面   过去,当我在循环中使用它们时   在NT上,我用LPTR作为标志   LocalReAlloc,它允许我   分配最多约512 KB。上   Windows CE,这种情况从未如此   分配多个KB。这个尺寸   限制它甚至对我们来说太小了   进程列表。改变了   LocalReAlloc标志为LMEM_MOVEABLE   适用于NT和CE并允许   内存达到最大的大小   自从以来分配的空闲块   呼叫后可以移动位置   到LocalAlloc而不是必须   扩大到位。

答案 2 :(得分:1)

据我所知,LHND甚至不是the Windows Mobile version of LocalAlloc中使用的有效标志。

当您使用LocalAlloc致电LMEM_MOVEABLE的非移动版时,返回类型 INFO_STRUCT*。返回类型为HLOCAL - 一个句柄到您已分配的内存中。它本身不是指针,因此将其取消引用就像指针一样不正确。要获得指针,您需要使用LocalLock告诉操作系统它暂时不能移动内存。

考虑what MSDN says about movable memory

  

可移动存储器标志LHND,LMEM_MOVABLE和NONZEROLHND增加了不必要的开销,需要锁定才能安全使用。应该避免使用它们,除非文档明确说明应该使用它们。

所以,如果你真的必须使用LocalAlloc,那么分配固定内存,而不是可移动的。这与调用普通旧malloc时的行为相同。

LMEM_MOVEABLE标志表示与LocalReAlloc不同的内容。而使用LocalAlloc它指定内存是否被锁定,LocalReAlloc它指定是否允许该函数移动内存以满足对更大内存块的请求。如果未将该标志包含LocalReAlloc,则该函数仅限于更改块的大小。如果那里没有空间,那么即使堆中其他地方有更大的内存块,该函数也会失败。

要获得malloc的效果,请致电LocalAlloc(LMEM_FIXED)。要获得realloc的效果,请致电LocalReAlloc(LMEM_MOVEABLE)。如果您愿意,请在任何一种情况下加入LMEM_ZEROINIT

从这一切中拿走的一件事似乎是你应该只使用文档明确指出你可以用于每个函数的标志。对于LocalAlloc,它没有提到LMEM_MOVEABLE,对于LocalReAlloc,它没有提到LPTR