9

I'm trying to write a size function like this:

size(void *p,int size);

Which would return the size of an array which is pointed to by p. For example:

Int *a = malloc((sizeof(int)*100));
size(a,sizeof(int)); // this should return 100

I think this is possible because if I recall, malloc keeps track of the space allocated in some header bytes.

Here's what I have so far:

int size(void *p, int size)
{
  p = (unsigned int *)p - 1;
  unsigned int elements = (*(unsigned int *)p);
  return elements/size;
}

Now, assuming that the size of the space allocated is in the 4 bytes before the pointer, this should return the bytes, or offset. This is where I'm a bit in the dark. I can't figure out the specifics of how malloc formats these header bytes. How does malloc pack the header bits?

Thanks, I appreciate this. I'm sure there are things wrong with this code and it's not particularly portable and may be very system dependent, but I'm doing it for fun.

kodai
  • 3,080
  • 5
  • 32
  • 34
  • 3
    If you can get this to work, it will only work on your particular implementation of `malloc`. Another system may use a different `malloc` and attempting to de-reference the pointer after moving it backwards past the end of the array might cause a memory access violation and crash your app. A more reliable way is to record the size of the memory region when you call `malloc`, and refer to that value instead of trying to dissect `malloc`'s metadata. – bta Oct 07 '10 at 23:20
  • Don't do this. If you need to know the size, store it yourself, but it's probably not even useful in most cases. Keep in mind that an advanced futuristic implementation of C will *not* store the size anywhere that's even reachable from your program, will not have casts between pointers and integer types, and will really trap and abort the program if you increment or decrement a pointer past the bounds of the object or try to do arithmetic on pointers to different objects. The standard allows this flexibility of implementation for very good reasons. – R.. GitHub STOP HELPING ICE Oct 08 '10 at 00:26
  • 1
    Suppose that your `malloc` is restricted to allocating power-of-two-sized blocks. Suppose that you have a dynamically-sized array of 12-byte objects, and request an initial capacity of 100. If you do things by the C standard, you have to `realloc` when your array grows to 100 elements. If you could get the actual size of the block, you could let your array grow to 170 elements before reallocating. So there's an efficiency advantage to being able to get the size of the block. – dan04 Oct 08 '10 at 02:50
  • 1
    @dan04: That's nonsense. On such an implementation, `realloc` will immediately see that the allocated size is already sufficient for the newly requested size, and return right away without doing anything. – R.. GitHub STOP HELPING ICE Oct 08 '10 at 05:01
  • @R..: You're assuming the next request will be for 101 elements. More realistically, it will be for 200, as exponential growth is required to keep appends having amortized constant time, and 2 is a common factor. Then you've got a 4096-byte block allocated to satisfy a request for 2400 bytes for an array with a logical size of only 1212 bytes. – dan04 Oct 08 '10 at 06:49
  • @Dan04: @R..: I am with R on this utter codswallup. – Martin York Oct 08 '10 at 07:33
  • @Martin: Please try refuting my facts instead of throwing insults. – dan04 Oct 08 '10 at 13:42
  • @dan04: I think it is you that has to prove something. You have made a postulate with no data and rambling incoherent assumptions no of which hold together. Provide some real facts and data to prove your assertations. As far as I can tell you are stringing nearly random concepts together to try and gain reputation with no substance or experience behind you assertions. So I repeat 'Codswallup'. Where I come from that means I don't believe you. Prove it. If you think being asked to prove it is an insult then tough. – Martin York Oct 08 '10 at 16:33
  • FACT: `malloc` is permitted to return a larger block than you ask it for, and implementations actually do this. In GCC, for example, `malloc_usable_size(malloc(1))` returns 24. – dan04 Oct 08 '10 at 16:53
  • Dup of [How can I get the size of an array from a pointer in C?](http://stackoverflow.com/questions/232691/how-can-i-get-the-size-of-an-array-from-a-pointer-in-c), [How I return the size of the pointer that I have allocate with malloc?](http://stackoverflow.com/questions/2478240/how-i-return-the-size-of-the-pointer-that-i-have-allocate-with-malloc) – outis Nov 29 '10 at 12:50

7 Answers7

6

In Visual Studio you can use _msize().

Matt Joiner
  • 112,946
  • 110
  • 377
  • 526
ruslik
  • 14,714
  • 1
  • 39
  • 40
6

If you like to peek and poke around beyond the memory your malloc() returns I recommend obtaining the source code of your allocator. This will be faster and safer than experimenting. ;-)

Peter G.
  • 14,786
  • 7
  • 57
  • 75
4

I think you're relying on some implementation-specific malloc() behaviour. The implementation of malloc() is system-specific and the specification mentions very little about how this is performed.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
2

There's no portable way to do this. As others have said, either look at your allocator's code if you're doing a one-off program just poking around, or for some libraries (MS) there are extensions like _msize. malloc is allowed to do what it wants inside the allocator to track stuff, and there's no "safe" or standard-compliant way of getting that data.

If you really need this capability reliably in a real application, you'll have to build a shim around malloc/free that keeps a table of allocation sizes.

Ben Zotto
  • 70,108
  • 23
  • 141
  • 204
1

You may find the glibc malloc-related functions to be of use. In particular you can call mallinfo() to get heap information. Some systems also define malloc_size, which is the BSD equivalent of _msize.

Matt Joiner
  • 112,946
  • 110
  • 377
  • 526
0

If you really want to go that route, dlmalloc (the malloc used on glibc and uClibc among others) has some docs at http://g.oswego.edu/dl/html/malloc.html. Also, googling for how to exploit heap overflows will probably get you details for every platform out there, including ones without source code available.

ninjalj
  • 42,493
  • 9
  • 106
  • 148
0

It's not in the standard. But there are platform-specific functions to do this, like _msize or malloc_usable_size.

dan04
  • 87,747
  • 23
  • 163
  • 198