Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can i know the allocated memory size of pointer variable in c [duplicate]

I have faced some problem in this case can you please your ideas.

main()
{
char *p=NULL;
p=(char *)malloc(2000 * sizeof(char));
printf("size of p = %d\n",sizeof (p));
}

In this program Its print the 4 that (char *) value,but i need how many bytes allocated for that.

like image 876
RoCkStUnNeRs Avatar asked Aug 26 '11 08:08

RoCkStUnNeRs


4 Answers

You could also implement a wrapper for malloc and free to add tags (like allocated size and other meta information) before the pointer returned by malloc. This is in fact the method that a c++ compiler tags objects with references to virtual classes. Here is one working example:

#include <stdlib.h>
#include <stdio.h>

void * my_malloc(size_t s) 
{
  size_t * ret = malloc(sizeof(size_t) + s);
  *ret = s;
  return &ret[1];
}

void my_free(void * ptr) 
{
  free( (size_t*)ptr - 1);
}

size_t allocated_size(void * ptr) 
{
  return ((size_t*)ptr)[-1];
}

int main(int argc, const char ** argv) {
  int * array = my_malloc(sizeof(int) * 3);
  printf("%u\n", allocated_size(array));
  my_free(array);
  return 0;
}

The advantage of this method over a structure with size and pointer

 struct pointer
 {
   size_t size;
   void *p;
 }; 

is that you only need to replace the malloc and free calls. All other pointer operations require no refactoring.

like image 195
StefanW Avatar answered Oct 01 '22 03:10

StefanW


Although it may be possible that some libraries allows you to determine the size of an allocated buffer, it wouldn't be a standard C function and you should be looking at your library's own documentations for this.

However, if there are many places that you need to know the size of your allocated memory, the cleanest way you could do it is to keep the size next to the pointer. That is:

struct pointer
{
    size_t size;
    void *p;
};

Then every time you malloc the pointer, you write down the size in the size field also. The problem with this method however is that you have to cast the pointer every time you use it. If you were in C++, I would have suggested using template classes. However, in this case also it's not hard, just create as many structs as the types you have. So for example

struct charPtr
{
    size_t size;
    char *p;
};
struct intPtr
{
    size_t size;
    int *p;
};
struct objectPtr
{
    size_t size;
    struct object *p;
};

Given similar names, once you define the pointer, you don't need extra effort (such as casting) to access the array. An example of usage is:

struct intPtr array;
array.p = malloc(1000 * sizeof *array.p);
array.size = array.p?1000:0;
...
for (i = 0; i < array.size; ++i)
    printf("%s%d", i?" ":"", array.p[i]);
printf("\n");
like image 30
Shahbaz Avatar answered Oct 01 '22 04:10

Shahbaz


There is no portable way but for windows:

#include <stdio.h>
#include <malloc.h>

#if defined( _MSC_VER ) || defined( __int64 ) /* for VisualC++ or MinGW/gcc */    
#define howmanybytes(ptr) ((unsigned long)_msize(ptr))
#else
#error no known way
#endif

int main()
{
  char *x=malloc(1234);

  printf( "%lu", howmanybytes(x) );

  return 0;
}
like image 29
user411313 Avatar answered Oct 01 '22 04:10

user411313


It is impossible to know how much memory was allocated by just the pointer. doing sizeof (p) will get the size of the pointer variable p which it takes at compile time, and which is the size of the pointer. That is, the memory the pointer variable takes to store the pointer variable p. Inside p the starting address of the memory block is stored.

Once you allocate some memory with malloc it will return the starting address of the memory block, but the end of the block cannot be found from it, as there is no terminator for a block. You define the end of the block therefore you need to identify it by any means, so store it somewhere. Therefore you need to preserve the block length somewhere to know where the block which is pointed to by p ends.

Note: Although the memory allocation structure keeps track of allocated and unallocated blocks, therefore we can know the allocated memory block length from these structures, but these structures are not available to be used by the users, unless any library function provides them. Therefore a code using such feature is not portable (pointed by @Rudy Velthuis) . Therefore it is the best to keep track of the structure yourself.

like image 24
phoxis Avatar answered Oct 01 '22 02:10

phoxis