Sender: nate AT cartsys DOT com Message-ID: <37B90842.4DA12D43@cartsys.com> Date: Mon, 16 Aug 1999 23:59:14 -0700 From: Nate Eldredge X-Mailer: Mozilla 4.08 [en] (X11; I; Linux 2.2.12pre4 i586) MIME-Version: 1.0 To: djgpp AT delorie DOT com CC: djgpp-workers AT delorie DOT com Subject: Re: Possible Bug in realloc() References: <7pa8ti$73k AT newsstand DOT cit DOT cornell DOT edu> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com 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