Mail Archives: djgpp-workers/1999/08/17/03:13:23
G wrote:
>
> Hi there,
> I've been using DJGPP for a couple of months now and am very impressed by
> it. Thanks to all of you who put forth all of the effort necessary to create
> it! I think that I may have come across a bug, however. When I was looking
> through the source code for realloc() I found the following lines in the
> code for realloc() :
> newptr= (char *)malloc(size);
> .
> .
> .
> memcpy(newptr, ptr, copysize);
> free(ptr);
> return newptr;
>
> It appears to me that when malloc is unable to allocate the requested
> amount of memory and returns NULL, data from the old block of memory(whose
> address is ptr) is copied to offset 0. I stepped through the code with RHIDE
> and this is what appears to happen. I'm pretty sure this is not what was
> intended. Of course, this is easy to fix by checking the newptr!=0 before
> the copy. Please let me know if I have made a mistake here.
This is indeed a bug. A patch (untested but "obviously correct" :) is
at the end of the message.
> Also, while on the subject, may I suggest a new function similar to
> realloc() that also changes the size of a memory block and copies data if
> necessary, but one the keeps the old block of memory reserved if it cannot
> allocate a larger block.
This is what `realloc' is supposed to do, AFAICT. My Linux man page
says: "If realloc() fails the original block is left untouched - it is
not freed or moved." Fixing the above bug should make it work like
this.
OTOH, the Single Unix man page doesn't mention this issue, but the
Linux-documented behavior is sane. Does ANSI discuss this?
> This would be very useful for times when one is
> building a growing set of data and doesn't want to lose it all when it can't
> be made any larger. I have thought of writing a function that does this
> using exising memory allocation functions such as malloc() but the problem
> with this approach is illustrated by the following example:
> Let's say you have 600 total units of space on the computer.
> Say 300 units are allocated in 1 large block and the subsequent 300 are
> free.
> If you want to enlarge the first block to 500 units, a "smart" realloc()
> could just enlarge the 300 unit block to 500 units if no block were already
> using the 200 units of space immediately following the 300 unit block.
> Malloc(), on the other hand would only see 300 free units(not knowing the
> 300 units already used could be part of the necessary 500) and so would deny
> the request for a 500 unit block whereas a "smart" reallloc could grant it.
> Unfortunately I don't know enogh of the internals of DJGPP memory blocks to
> write such a function, but if anyone has such a function I would love to
> know about it.
It's true, DJGPP's realloc could be smarter in that respect. On the
other hand, I think it's currently optimized for speed rather than
efficient memory usage, so it might not be felt to be worth it.
> Thanks for your time, I hope I have been of some help.
Thanks for the bug report.
--- src/libc/ansi/stdlib/malloc.c Thu Jun 3 14:13:20 1999
+++ src/libc/ansi/stdlib/malloc.c.new Mon Aug 16 23:58:04 1999
@@ -348,6 +348,8 @@
}
newptr = (char *)malloc(size);
+ if (!newptr)
+ return NULL;
#if DEBUG
printf("realloc %u %u/%08x %08x->%08, %u\n",
size, b->size & ~1, b, ptr, newptr, copysize);
--
Nate Eldredge
nate AT cartsys DOT com
- Raw text -