How to Get the Size of a Memory Block Allocated Using Malloc()

Determine size of dynamically allocated memory in C

comp.lang.c FAQ list · Question 7.27 -

Q. So can I query the malloc package to find out how big an
allocated block is?

A. Unfortunately, there is no standard or portable way. (Some
compilers provide nonstandard extensions.) If you need to know, you'll
have to keep track of it yourself. (See also question 7.28.)

How can I get the size of a memory block allocated using malloc()?

It's not standard but if your library has a msize() function that will give you the size.

A common solution is to wrap malloc with your own function that logs each request along with the size and resulting memory range, in the release build you can switch back to the 'real' malloc.

How to get memory block length after malloc?

What you're doing is definitely wrong. While it's almost certain that the word just before the allocated block is related to the size, even so it probably contains some additional flags or information in the unused bits. Depending on the implementation, this data might even be in the high bits, which would cause you to read the entirely wrong length. Also it's possible that small allocations (e.g. 1 to 32 bytes) are packed into special small-block pages with no headers, in which case the word before the allocated block is just part of another block and has no meaning whatsoever in relation to the size of the block you're examining.

Just stop this misguided and dangerous pursuit. If you need to know the size of a block obtained by malloc, you're doing something wrong.

Getting the size of a malloc only with the returned pointer

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);

Visual Studio 2010 C++: Get size of memory block allocated by malloc

In Visual C++ you can use _msize() for that.

What is the size of variable after using malloc()?

I always find that pictures help in a situation like this.

The declaration

char *s;

creates a single object of type char *:

char *
+---+
| | s
+---+

with an indeterminate value (not necessarily 0 or any particular value, may be different each time the program is run).

The statement

s = (char*)malloc(1024 * sizeof(char));

allocates space for 1024 char objects somewhere else in memory, and assigns the address of the first object in that space to s:

char *        char
+---+ +---+
| | s ----> | | s[0]
+---+ +---+
| | s[1]
+---+
| | s[2]
+---+
...

The size of the s variable never changes, only its value. In this case, its value is the address of s[0].

So why not returns 8192 as size after allocating memory. Further when I added chars into s why not getting as 4 ?

sizeof(s) gives you the size of the pointer variable itself, not the size of the object to which it is pointing. You want to write that call as

printf("Size actual: %d\n", sizeof *s * 1024);

The type of s is char *, which is going to be greater than 1 on any real world system (4 or 8, depending). The type of the expression *s is char, which is what you want to use here.

Further when I added chars into s why not getting as 4 ?

You haven't added anything to s (or more properly, the buffer it points to) - you've only assigned new values to things that were already there. You allocated space for 1024 char objects, and that size doesn't change just by assigning elements. Critically, something like

s[1026] = some_value;

doesn't automatically extend the allocated memory - you're just writing outside of the bounds of that memory. You have to use the realloc library call to increase the size of the allocated block.

Additionally,

printf("Size by calculation: %d", sizeof(s) / sizeof(char));

doesn't do what you're expecting - Again, sizeof(s) gives you the size of the pointer variable itself, not the size of the thing to which it is pointing. sizeof(*s) won't work either, because that gives you the size of a single char object, not the entire allocated space. You have to keep track of how much space you allocated in a separate variable:

size_t num_elements = 1024;
char *s = malloc( sizeof *s * num_elements );

Like I said above, if you need to extend that space later on, you need to use the realloc function:

/**
* Double the size of the allocated block.
*/
char *tmp = realloc( s, sizeof *s * (num_elements * 2) );
if ( tmp )
{
s = tmp;
num_elements *= 2;
}

If realloc cannot successfully extend the buffer, it will return NULL and leave the original buffer in place. Because of this, we want to assign the result to a temporary variable - we don't want to risk s being set to NULL and thus losing our only reference to that memory. Similarly, we don't want to update the size until we know the realloc call was successful.

Some style notes -

As of C89, the cast on malloc (and calloc and realloc) is unnecessary and generally considered bad practice. The more common practice is

T *p = malloc( sizeof *p * N ); // for any type T

Since the expression *p has type T, sizeof *p is equivalent to sizeof (T). This way you're not repeating type information multiple times in a single malloc call, which eases the maintenance burden (fewer things to update if T ever changes). This is not true in C++ and a cast is still required on malloc, calloc, and realloc, but if you're writing C++ you shouldn't be using C-style memory management in the first place.

Also, remember that sizeof is an operator, not a function - parentheses are only necessary if the operand is a type name or is an expression containing arithmetic or other operators of lower precedence. For example,

sizeof x+y

is parsed as

(sizeof x) + y

If you want the size of the expression x+y, then you need to write

sizeof (x+y)

dynamic memory allocation in c , free some part of memory that is allocated before using malloc()

You should use the standard library function realloc. As the name suggests, it reallocates a block of memory. Its prototype is (contained in the header stdlib.h)

 void *realloc(void *ptr, size_t size);

The function changes the size of the memory block pointed to by ptr to size bytes. This memory block must have been allocated by a malloc, realloc or calloc call. It is important to note that realloc may extend the older block to size bytes, may keep the same block and free the extra bytes, or may allocate an entirely new block of memory, copy the content from the older block to the newer block, and then free the older block.

realloc returns a pointer to the block of reallocated memory. If it fails to reallocate memory, then it returns NULL and the original block of memory is left untouched. Therefore, you should store the value of ptr in a temp variable before calling realloc else original memory block will be lost and cause memory leak. Also, you should not cast the result of malloc - Do I cast the result of malloc?

// allocate memory for 10 integers
int *arr = malloc(10 * sizeof *arr);
// check arr for NULL in case malloc fails

// save the value of arr in temp in case
// realloc fails
int *temp = arr;

// realloc may keep the same block of memory
// and free the memory for the extra 5 elements
// or may allocate a new block for 5 elements,
// copy the first five elements from the older block to the
// newer block and then free the older block
arr = realloc(arr, 5 * sizeof *arr);
if(arr == NULL) {
// realloc failed
arr = temp;
}

How to determine the size of an allocated C buffer?

buffer is just a pointer without size information. However the malloc() routine will hold the size of the allocation you made so when you free() it, it frees the right amount of space. So unless you want to dive in the malloc() functionality, I recommend you just save the size of the allocation yourself. (for a possible implementation, see the example in the other API answer).



Related Topics



Leave a reply



Submit