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