Getting the size of a malloc only with the returned pointer
Asked Answered
V

6

8

I want to be able to vary the size of my array so I create one this way:

int* array;
array = malloc(sizeof(int)*10);//10 integer elements

I can use this like an array as you normally would, however when I try to find the size of it like so:

size = sizeof(array)/sizeof(int);

I get the answer 1 because its not recognizing it as pointing to an array

How can I get the size of the array ? (I know its not technically an array but is there a way to work out the whole size of the allocated memory block ?)

Also am I right in assuming what I have stated in the description ? If I am technically wrong about something please correct me.

Vincenty answered 26/8, 2012 at 16:42 Comment(1)
You can't do it. sizeof doesn't know about malloc.Crunode
C
13

The pointer is a pointer, and not an array. It can never be "recognized as an array", because it is not an array.

It is entirely up to you to remember the size of the array.

For example:

struct i_must_remember_the_size
{
    size_t len;
    int * arr;
};

struct i_must_remember_the_size a = { 10, NULL };
a.arr = malloc(a.len * sizeof *a.arr);
Colunga answered 26/8, 2012 at 16:47 Comment(2)
How does free(arr) know how much memory to free if the size that has been allocated with malloc is not actually known?Nevski
@Zulakis: free just informs the system allocator that the allocation corresponding to the pointer value has been freed. It's up to the system allocator's implementation to keep enough bookkeeping information around to make sense of that request. For example, if the allocator maintains arenas for different sizes, then the pointer value itself could indicate which arena it came from.Colunga
R
5

In C standard and portable, it's impossible. Just notice that some compilers provide nonstandard extensions (keep track of it, e.g. msize).

Besides, the sizeof operator can't tell you the size of the block, so it yields the size of the pointer (remember that sizeof operates at compile time, except with variable length arrays).

So you have to keep the size alloced, e.g. in a data structure such as :

#include <stddef.h>

typedef struct {
    int   *p;
    size_t n;
} array;
Remindful answered 26/8, 2012 at 16:45 Comment(0)
B
3

There's no standard way to do what you ask. Some compilers may provide a function for that, or some other allocators may have such a function, but, as already said there's nothing standard.

Notice that the sizeof applied over arrays does not work because it recognizes the pointer "as from an array": it just recognizes its argument as an array (sizeof is one of the few contexts in which an array do not decay to a pointer to its first element); once your array decays to a pointer sizeof will only yield the size of the pointer.

Bestow answered 26/8, 2012 at 16:45 Comment(0)
P
3

First of all, sizeof() returns the size of a "type"; it doesn't know a thing about allocated memory.

Second, there is no way to get the size of a malloc()ed block, UNLESS you want to dig into the internals of the runtime library of your compiler. Which is most definitely not a good idea, especially since it's no problem to remember the size elsewhere --- you could prefix the memory block with another item to store the size, or you could store it separately.

Pluri answered 26/8, 2012 at 16:47 Comment(0)
S
2

Use a pointer-to-array type rather than a pointer-to-element type:

int (*parray)[10] = malloc(sizeof *parray);

Then sizeof *parray gives you the desired answer, but you need to access the array using the * operator, as in (*parray)[i] (or equivalently albeit confusingly, parray[0][i]). Note that in modern C, 10 can be replaced with a variable.

Swing answered 26/8, 2012 at 18:42 Comment(1)
"Modern C"—C99 (and C11) support VLAs, to be specific.Therapeutic
B
1

What you seek is malloc_usable_size(void *ptr), which is a GNU extension.

The gotcha here is that you might allocate a number of bytes like seven, but the malloc allocator will return the first greater binary buddy from the malloc arena. The function malloc_usable_size is said to return the size of the actually allocated block, not the size requested from malloc().

From: man page

SYNOPSIS

       #include <malloc.h>

       size_t malloc_usable_size(void *ptr);

DESCRIPTION

       The malloc_usable_size() function returns the number of usable
       bytes in the block pointed to by ptr, a pointer to a block of
       memory allocated by malloc(3) or a related function.

NOTES

   The value returned by malloc_usable_size() may be greater than
   the requested size of the allocation because of alignment and
   minimum size constraints.  Although the excess bytes can be
   overwritten by the application without ill effects, this is not
   good programming practice: the number of excess bytes in an
   allocation depends on the underlying implementation.

   The main use of this function is for debugging and introspection.
Brennen answered 4/4, 2023 at 17:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.