[comp.lang.c] To find out the names of open files in a process

brett@wjvax.UUCP (Brett Galloway) (01/30/88)

>In article <1427@mips.mips.COM> hansen@mips.COM (Craig Hansen) writes:
>>In article <904@thorin.cs.unc.edu>, gallmeis@wasp.cs.unc.edu (Bill Gallmeister) writes:
>>> this kind of reminds me of someone who asked how to get the size of a malloc'ed block.
>>> The answer?  "Remember how much you asked for, dimwit!"
>>
>>Actually, if free() is going to be able to deallocate the space, the
>>dimwit malloc() ought to be salting the size away somewhere, since
>>free doesn't depend on the dimwit programmer telling it how big the
>>block is. With that in mind, there's no conceivable reason why there
>>isn't an msize() function for us comp.unix.dimwits.

I don't agree that only dimwits require this information.  All
implementations of malloc() will give you *at least* the amount of room
you asked for; many will give you more (BSD is reputed to allocate in
powers of 2).  I have several applications where I could make more
efficient use of space if I knew how much space malloc() actually gave
me.  This occurs whenever I am malloc()'ing a buffer that I may want
to realloc() later because it filled up; knowing how much malloc()
actually gave me could save both malloc space and run-time.

I suggested this on comp.lang.c a while back as a useful, portable
enhancement to any malloc() package, but got no response.  I have
redirected follow-ups back to comp.lang.c because it seems of general
interest to users of standard C libraries with a malloc() routine.

-- 
-------------
Brett D. Galloway
{ac6,calma,cerebus,isi,isieng,pyramid,tymix}!wjvax!brett

brett@wjvax.UUCP (Brett Galloway) (02/01/88)

In article <2672@bloom-beacon.MIT.EDU> eichin@athena.mit.edu (Mark W. Eichin) writes:
>>[why isn't there an msize() routine that returns the actual amount of space
>>allocated by malloc()?]
>In summary: there IS a reason that there isn't an msize() by default,
>it is a constraint upon the allocator which can be overly restrictive
>in certain usage patterns.

I posted the other day another reason for making such a feature (a feature
to return the *actual* malloc()'d size available to the user) available.
I neglected to mention that I was thinking in terms of a variant malloc()
that returned the actual size as well as the character pointer.  I agree that
an after-the-fact msize() routine might be overly expensive.  However, it seems
to me that a variant malloc() that reported what it actually allocated could
be had for free.  I mean a routine like

	char	*mallocsize(size,actual)
	unsigned size;
	unsigned *actual;

(with types ala BSD -- fill in your own types).  If the implementor were
lazy, or forgot to implement it at all, he (or you) could just use

	char	*mallocsize(size,actual)
	unsigned size;
	unsigned *actual;
	{
		*actual = size;
		return(malloc(size));
	}
-- 
-------------
Brett D. Galloway
{ac6,calma,cerebus,isi,isieng,pyramid,tymix}!wjvax!brett

rbutterworth@watmath.waterloo.edu (Ray Butterworth) (02/02/88)

In article <1209@wjvax.UUCP>, brett@wjvax.UUCP (Brett Galloway) writes:
> I don't agree that only dimwits require this information.  All
> implementations of malloc() will give you *at least* the amount of room
> you asked for; many will give you more (BSD is reputed to allocate in
> powers of 2).  I have several applications where I could make more
> efficient use of space if I knew how much space malloc() actually gave
> me.  This occurs whenever I am malloc()'ing a buffer that I may want
> to realloc() later because it filled up; knowing how much malloc()
> actually gave me could save both malloc space and run-time.

My buffer growing applications typically look something like this:

dosomething(size_t bytes_needed, other-args) {
    static size_t bytes = 0;
    static char *buffer = 0;

    if (bytes_needed > bytes) {
        if (buffer)
            free((malloc_t)buffer);
        while (bytes < bytes_needed)
            bytes = (bytes*2) + 4;
        buffer = (char *)malloc(bytes);
        if (!buffer) {
            perror("malloc");
            exit(ERROR_EXIT);
        }
    }

    finally-do-it;
    return;
}

The "(bytes*2)+4" is based on the BSD malloc growth.
The algorithm would be very wasteful on many other systems,
but anything else would be very wasteful on all systems.

> I suggested this on comp.lang.c a while back as a useful, portable
> enhancement to any malloc() package, but got no response.  I have
> redirected follow-ups back to comp.lang.c because it seems of general
> interest to users of standard C libraries with a malloc() routine.

Being able to determine the appropriate growth increment at run-time
(or even compile-time) would defintely be useful.

flaps@csri.toronto.edu (Alan J Rosenthal) (02/02/88)

In article <1209@wjvax.UUCP> brett@wjvax.UUCP (Brett Galloway) writes:
[ on: having a function to return the amount of size in a malloc'd block ]
>All implementations of malloc() will give you *at least* the amount of
>room you asked for; many will give you more.  I have several
>applications where I could make more efficient use of space if I knew
>how much space malloc() actually gave me.  This occurs whenever I am
>malloc()'ing a buffer that I may want to realloc() later because it
>filled up; knowing how much malloc() actually gave me could save both
>malloc space and run-time.

I don't see why this would save you time.

If the value you call realloc() with is greater than the malloc() value
but less than the amount actually allocated, obviously nothing will
happen.  For definiteness, I just verified this by looking at the
sources for Sun Unix 3.3, but I can't imagine a non-silly
implementation in which this would not be true.

In fact, I'd make a case for realloc() being a no-op if the realloc()
value is only slightly less than the original allocation.  In other
words, if you asked for 100 bytes before, and now you realloc() that
to 90, maybe realloc() should say "well it's not worth the bother to
reduce it".  (This would be legitimate behaviour as you can always give
the user MORE memory than they've asked for.)

Also in fact, Sun 3.3 realloc() seems to do that, although it appears
to have been an oversight rather than a deliberate decision, and it
only gives you a 4-byte leeway.  (Details:  The "smallest block" is
defined as an unsigned int plus an array 4 of char, 4 being the deduced
alignment requirement as it is sizeof(int).  The test in realloc() for
whether or not it should do anything is
	    if (oldsize - newsize >= SMALLEST_BLK)
, where SMALLEST_BLK is sizeof(struct { unsigned int size; char data[4]; }).)

ajr