[comp.unix.wizards] Finding size of a malloc

djfiander@watmath.waterloo.edu (David Fiander) (02/04/88)

In article <461@minya.UUCP> jc@minya.UUCP (John Chambers) 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.
:Of course, a good design would always pass a size along with a pointer.
:Sure, and when you are writing your library sprintf() routine, do you
:want to go out and modify all the calls in all the software in the world
:so that there's a size parameter?  I mean, sprintf() is specified and 
:cast in a huge chunk of concrete by now.  It doesn't include a size field.
:How is a competent software engineer to guarantee that it doesn't overflow
:the caller's array?

The only problem with this is that I usually call sprintf() with a statically
allocated array and, the last time I looked, they _don't_ have sizes associated
with them.  It would be nice to be able to find out the size of a malloc()ed 
block, but first we have to be able to figure out if the pointer we have
actually points at something from malloc().

-- 
It was one of themselves, one of their own prophets, who said,
"Cretans were never anything but liars, dangerous animals and lazy": and
that is a true statment.
	- Titus 1:12

UUCP  : {allegra,ihnp4,decvax,utzoo,clyde}!watmath!djfiander
CSNET : djfiander%watmath@waterloo.CSNET

hunt@spar.SPAR.SLB.COM (Neil Hunt) (02/06/88)

On malloc on V6, V7 and BSD:

On several UNIXs, malloc returns pretty much exactly the space you ask for;
however, it does call sbrk to obtain memory from the system
in larger chunks, which it maintains itself.

The size parameter is often stored in an integer word immediately
preceeding the returned block; hence:

#define Malloc_size(p)	(*((int *)p) - 1)

For the person who wants to save items incrementally: don't use
malloc and realloc for each item - it's too expensive.
Use a linked list. But don't malloc each block separately:

#define N_ALLOC 1000

struct item *
new_item()
{
	static struct item *free_list = NULL;
	struct item *p;

	/*
	 * If the free list is empty..
	 */
	if(free_list == NULL)
	{
		/*
		 * Allocate N_ALLOC items.
		 */
		if((free_list = (struct item *)calloc(
		  sizeof(struct item), N_ALLOC)) == NULL)
			prexit("Out of memory\n");

		/*
		 * Link them together
		 */
		for(p = free_list; p < free_list + N_ALLOC - 1; p++)
			p->next = p + 1;
	}

	/*
	 * Obtain the next free item.
	 */
	p = free_list;
	free_list = p->next;
	p->next = NULL;

	/*
	 * Return it.
	 */
	return p;
}

As an alternative to linking the new free items into a linked list
in the static free_list, just use a counter of remaining free items.

If you are freeing your items as well as allocating them,
then move the free list to a file static variable and write a free_item
function which returns used items to the free list.

Neil/.