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