我正在用win32 api用c编写一个应用程序。
当我试图使用heaprelloc()函数扩大数组的大小时,它会更改数组中的当前值,而不是复制它们。
我用来重新分配内存的代码:

BOOL ChangeFeedArraySize(UINT newSize)
{
    char tempChar[20] = "";
    PFEED tempArr;
    if (newSize == 1)
    {
        tempArr = (PFEED)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(FEED));
    }
    else
    {
        tempArr = (PFEED)HeapReAlloc(heap, HEAP_ZERO_MEMORY, categoryArray, newSize * sizeof(FEED));
        // FEED - a struct
        // PFEED - a pointer to the struct
        // categoryArray - array to be reallocated
    }

    if (tempArr != NULL)
    {
        MessageBox(NULL, ltoa(HeapSize(heap, 0, tempArr),tempChar,10) , "Heap size after reallocation", MB_OK | MB_ICONEXCLAMATION);
        feedArray = tempArr;
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

这是在断点中数组的状态。
feed数组显示当前数组状态。
临时数组显示新的重新分配数组状态(这是不同的)。
馈送数组:
feedArray http://www.freeimagehosting.net/uploads/526b0b2172.jpg
临时数组:
tempArray http://www.freeimagehosting.net/uploads/17858f2e7e.jpg
请帮忙..:。\
链接到MSDN

最佳答案

您引用了一个特定于windows的函数,但对于标准等效函数realloc(),也是如此。
如果这些函数返回的地址与传入的地址相同,那是因为您最初请求的缓冲区后面的内存未使用。这样就可以在不移动缓冲区的情况下满足请求。
但是,如果有两个快速分配在立即连续,例如?可能在最初请求之后的内存最终被用于下一次分配。在这种情况下,分配器需要在其他地方找到空间,复制旧缓冲区中的内容,释放旧缓冲区,然后返回新缓冲区。
一般来说,您要遵循的模式是这样的:

void *newmem = realloc(oldmem, newsize);
if (!newmem)
{
   // TODO: handle failure
   // possibly free(oldmem); depending on how you want to handle errors
}
else
{
   oldmem = newmem;
}

人们通常走的捷径是“oldmem = realloc(oldmem, newsize);”,但这并不像上面那样优雅,因为当出现故障时,它会泄漏。
根据您的编辑进行更新:
在你的代码中我想知道的是这一部分:
if (newSize == 1)
{
    tempArr = (PFEED)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(FEED));
}

这似乎假设第一个分配总是大小为1。你确定你不是想说oldmem,然后分配if (feedArray == NULL)
第二次更新:
好啊。另一个突出的问题是:
temparr=(pfeed)堆分配(堆,堆零内存,类别数组,
新闻大小*sizeof(feed));
//snip…
如果(坦帕!=空)
{
//snip…
feedArray=temparr;
粗体部分应该相同。

10-07 15:17