[comp.unix.questions] malloc question

andy@garnet.berkeley.edu (Andy Lieberman) (06/13/89)

I want to write a function that will return the size of a memory
block that was allocated with malloc.  How can I determine this
knowing only the pointer to the start of the block? (I know I
could keep track myself, but I don't see why I should have to.)
I'm using SUNOS 3.5.  

Please reply by e-mail and I will post a summary.

Thanks,
Andy Lieberman
andy@library.Berkeley.EDU

andy@garnet.berkeley.edu (Andy Lieberman) (06/15/89)

In article <25424@agate.BERKELEY.EDU> I wrote:
>I want to write a function that will return the size of a memory
>block that was allocated with malloc.  How can I determine this
>knowing only the pointer to the start of the block? (I know I
>could keep track myself, but I don't see why I should have to.)
>I'm using SUNOS 3.5.  
>

Tony Olekshy (...!alberta!oha!tony or tony@oha.UUCP) replies:

This is not portable, but most malloc() keep the size of the block in
an int just before the block (ie, they allocate sizeof(int) more bytes
than you ask for, and return you a pointer sizeof(int) bytes into the
block).  So, if p is a char* from malloc, you can usually use something
like *(int *)(p - sizeof(int)).
-- 


David Elliott		dce@Solbourne.COM
			...!{boulder,nbires,sun}!stan!dce
replies:

It depends on what you mean by the size of the memory block.

If you want the size of the block that malloc gave you, you can
decode the data found before the block (malloc stores a "bucket number"
in the area before the block, and you do exponentiation on the number
to get the size of the blocks in that bucket).  This is highly unportable,
and Sun could easily change malloc in the future, so be forewarned.

If you want the size of the data you asked for, that isn't stored.  For
speed, malloc just gives you a pointer to a block of memory whose size
is usually the next power of 2 above the size you asked for (depending
on alignment and so forth).  So, if you need the size you asked for,
you'll need to write some code (or more likely someone will send you
the code since this topic has come up a couple of times before) to
do something like maintain a table of sizes for you.
-- 


I used Tony's method which seems to return a number four larger than what I
would expect (e.g., for a malloc(1024), Tony's function returns 1028).

Thanks for all the responses,
Andy Lieberman

cline@image.soe.clarkson.edu (Marshall Cline) (06/16/89)

In article <25471@agate.BERKELEY.EDU> andy@garnet.berkeley.edu (Andy Lieberman) writes:

>In article <25424@agate.BERKELEY.EDU> ?Andy?Lieberman? wrote:
>>I want to write a function that will return the size of a memory
>>block that was allocated with malloc.  How can I determine this
>>knowing only the pointer to the start of the block? (I know I
>>could keep track myself, but I don't see why I should have to.)
>>I'm using SUNOS 3.5.  
>>

Tony Olekshy (...!alberta!oha!tony or tony@oha.UUCP) replies:
>This is not portable, but most malloc() keep the size of the block in
>an int just before the block (ie, they allocate sizeof(int) more bytes
>than you ask for, and return you a pointer sizeof(int) bytes into the
>block).  So, if p is a char* from malloc, you can usually use something
>like *(int *)(p - sizeof(int)).

>[...more portability warnings deleted...]

Not to be picky, but wouldn't that be a "size_t" rather than an "int"?
Ie: You want the pointer minus "sizeof(size_t)" bytes.  Thus:
	*(int *)((char *)p - sizeof(size_t))
(Note that I added an explicit "(char *)" cast to "p", which Tony
correctly implied in the discussion above).

Again the stern warning: Unportable, unportable, unportable.
The only reason to avoid malloc'ing another extra "sizeof(size_t)"
bytes is convienence (memory is relatively cheap compared to the
increased maintenance cost for unportable code), yet it is _very_
inconvienent to maintain poorly written stuff.
My opinion: Convienence and memory costs are minimal. Do it right.

Note: if you're doing a billion malloc's, one could argue that the
memory savings would be valid.  But if you're doing a billion
memory allocations, there certainly are better alternatives than
a billion malloc()'s (such as a few big malloc's each of which is
chopped up into smaller blocks).  Point being that malloc() is
inefficient (both space-wise and time-wise) when used to allocate
billions of tiny blocks of memory.

Conclusion: Store the size of the memory block (or rather the size
you asked for) in a "size_t" variable rather than peeking and poking.

Marshall
--
	________________________________________________________________
	Marshall P. Cline	ARPA:	cline@sun.soe.clarkson.edu
	ECE Department		UseNet:	uunet!sun.soe.clarkson.edu!cline
	Clarkson University	BitNet:	BH0W@CLUTX
	Potsdam, NY  13676	AT&T:	(315) 268-6591