我正在用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;
粗体部分应该相同。