Reputation: 1150
Allocating memory dynamically using malloc will return the address from where the memory is allocated. Before that address meta-data is stored; it's a struct.
struct malloc_chunk {
int prev_size;
int size; // size of memory allocated
struct malloc_chunk* fd;
struct malloc_chunk* bk;
struct malloc_chunk* fd_nextsize;
struct malloc_chunk* bk_nextsize;
};
I want to print value of size without using malloc_usable_size(). I tried but I am getting a segfault. I am working on 64-bit Ubuntu.
Upvotes: 0
Views: 2899
Reputation: 753695
Consider the following test code (which has no error checking):
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void *v1 = malloc(160);
void *v2 = malloc(160);
void *v3 = malloc(160);
printf("v1 = %p\n", v1);
printf("v2 = %p\n", v2);
printf("v3 = %p\n", v3);
ptrdiff_t d1 = v2 - v1;
ptrdiff_t d2 = v3 - v2;
printf("d1 = %td\n", d1);
printf("d2 = %td\n", d2);
return 0;
}
When compiled on 64-bit Ubuntu 14.04 LTS, the output I got was:
v1 = 0x742010
v2 = 0x7420c0
v3 = 0x742170
d1 = 176
d2 = 176
Since the gap between the returned blocks is 176 bytes and the size allocated is 160 bytes, there are just 16 bytes of overhead. The struct malloc_chunk
outlined in the question occupies 40 bytes on a 64-bit platform (24 on a 32-bit platform). It does not fit into the space between allocated chunks of memory.
Therefore, any attempt to access a struct malloc_chunk
from a regular block of allocated memory is doomed to failure.
You will have to obtain the source to malloc()
to find out how it uses that structure. If I had to guess, it uses it in a separate area altogether. Maybe some of the 16 bytes of overhead tells malloc()
where to find the struct malloc_chunk
. But that's a guess; I've not looked.
Upvotes: 3
Reputation: 13690
The structure is implementation dependent. You should not use the information at all since it might change at the next compiler or even at the next compiler version.
You should manage the size of memory in user defined structures.
Edit: Memory allocation algorithms usually work with some alignments to
Therefore malloc
doesn't need to allocate exactly the size that you passed as parameter. It can allocate a chunk the is sufficient to hold the requested size but probably more. It's not necessary for malloc
to store the original value, only the chunk size is necessary to free
the chunk.
Therefore it's probably impossible to retrieve the size parameter passed in the malloc
function call.
Upvotes: 4
Reputation: 6407
First of all malloc_usable_size
is Linux/Unix specific function and will not work on Windows, for example.
So, the best way is to save size when allocating memory: just remember how much memory was allocated and than use that value.
Upvotes: 2
Reputation: 12668
Malloc library normally maintains a list of struct malloc_chunk
internally to manage the amounts of memory given to the user up to this point. Normally, to cope with that they have a way to map the returned pointer from malloc(3) to the address of this structure (so free(3) can get to it), but you don't know that mapping for sure.
Normally, they alloc internally the amount to store the memory they give to you and this struct malloc_chunk
together, and the struct is aligned in a way that they can get the structure address from the pointer you pass to free(3)
.
The normal way to cope with this is: The malloc(3) function gives you (void *)(ref + 1)
, where ref
is a struct malloc_chunk *
pointer (so it's aligned to the end of this structure) and you have to do just the opposite to get a valid pointer to that structure, that is: ((struct malloc_chunk *)ptr - 1)
(convert the pointer to a struct malloc_chunk *
pointer, and then go back one structure size to point there)
This expression is of type pointer to struct malloc_chunk
, so you can reference its fields with the following code:
void *p = malloc(120);
struct malloc_chunk *mc = (struct malloc_chunk *)p - 1;
printf("prev_size: %d\n"
"size: %d\n"
"fb: %p\n"
"bk: %p\n"
"fw_nextsize: %p\n"
"bk_nextsize: %p\n",
mc->prev_size,
mc->size,
mc->fb,
mc->bk,
mc->fw_nextsize,
mc->bk_nextsize);
I have not been able to test this code, as my <malloc.h>
implementation doesn't have this struct malloc_chunk
type defined anywhere (or I have not been able to find it). You have to provide a reference of where do you have acquired this type if you want me to be able to reproduce your environment. I'm using gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
Upvotes: 1
Reputation: 106539
In the general case, the exact mechanism malloc
uses to store the size -- if it even has a mechanism -- is going to be implementation defined. You need to keep track of the size yourself if you need it for anything specific.
Upvotes: 3