msvcrt: fix _aligned_offset_realloc (move correct block of memory); add a comment to explain why.
Lionel Debroux
lionel_debroux at yahoo.fr
Sun Nov 25 02:54:59 CST 2007
---
dlls/msvcrt/heap.c | 39 ++++++++++++++++++++++++++++++++++-----
1 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/dlls/msvcrt/heap.c b/dlls/msvcrt/heap.c
index 78739d5..33dc3ce 100644
--- a/dlls/msvcrt/heap.c
+++ b/dlls/msvcrt/heap.c
@@ -434,7 +434,7 @@ void * CDECL _aligned_offset_realloc(void *memblock, MSVCRT_size_t size,
return NULL;
}
- old_padding = (char *)*saved - (char *)memblock;
+ old_padding = (char *)memblock - (char *)*saved;
temp = MSVCRT_realloc(*saved, size + alignment + sizeof(void *));
@@ -448,11 +448,40 @@ void * CDECL _aligned_offset_realloc(void *memblock, MSVCRT_size_t size,
/* so it can be found later to free. */
saved = SAVED_PTR(memblock);
- /* a new start address may require different padding to get the */
- /* proper alignment */
- new_padding = (char *)temp - (char *)memblock;
+ new_padding = (char *)memblock - (char *)temp;
+
+/*
+ Memory layout of old block is as follows:
+ +-------+---------------------+-+--------------------------+-----------+
+ | ... | "old_padding" bytes | | ... old size bytes ... | ... |
+ +-------+---------------------+-+--------------------------+-----------+
+ ^ ^ ^
+ | | |
+ *saved saved memblock
+
+ Memory layout of new block is as follows:
+ +-------+-----------------------------+-+----------------------+-------+
+ | ... | "new_padding" bytes | | ... "size" bytes ... | ... |
+ +-------+-----------------------------+-+----------------------+-------+
+ ^ ^ ^
+ | | |
+ temp saved memblock
+
+ However, in the new block, actual data is still written as follows
+ (because it was copied by MSVCRT_realloc):
+ +-------+---------------------+--------------------------------+-------+
+ | ... | "old_padding" bytes | ... old size bytes ... | ... |
+ +-------+---------------------+--------------------------------+-------+
+ ^ ^ ^
+ | | |
+ temp saved memblock
+
+ Therefore, "size" bytes of actual data have to be moved from the offset
+ they were at in the old block (temp + old_padding) to the offset they
+ have to be in the new block (temp + new_padding == memblock).
+*/
if (new_padding != old_padding)
- memmove((char *)memblock + old_padding, (char *)memblock + new_padding, size);
+ memmove((char *)memblock, (char *)temp + old_padding, size);
*saved = temp;
--
1.5.3.4
--0-2113887043-1196068139=:70316--
More information about the wine-patches
mailing list