www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/08/17/03:13:23

Sender: nate AT cartsys DOT com
Message-ID: <37B90842.4DA12D43@cartsys.com>
Date: Mon, 16 Aug 1999 23:59:14 -0700
From: Nate Eldredge <nate AT cartsys DOT com>
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>
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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019