How to determine the size of an allocated C buffer

2019-01-15 01:08发布

问题:

I have a buffer and want to do a test to see if the buffer has sufficient capacity I.e. find number of elements I can add to the buffer.

char *buffer = (char *)malloc(sizeof(char) * 10);

Doing a

int numElements = sizeof(buffer); 

does not return 10, any ideas on how I can accomplish this?

回答1:

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



回答2:

For GNU glibc:

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.



回答3:

You cannot make such a test. It is your own responsibility to remember how much memory you allocated. If the buffer is given to you by someone else, demand that they pass the size information as well, and make it their responsibility to pass the correct value or have the program die.



回答4:

Since buffer is a pointer (not an array), the sizeof operator returns the size of a pointer, not the size of the buffer it points to. There is no standard way to determine this size, so you have to do the bookkeeping yourself (i.e. remember how much you allocated.)

BTW, it's the same for

 char *p = "hello, world\n"; /* sizeof p is not 13. */

Interestingly,

 sizeof "hello, world\n"

is 14. Can you guess why?



回答5:

struct buffer
{
  void
    *memory

  size_t
    length;
};

void *buffer_allocate( struct buffer *b, size_t length )
{
  assert( b != NULL );

  b->memory = malloc( length )
  b->length = length;

      // TRD : NULL on malloc() fail
      return( b->memory );
}

int buffer_valid( struct buffer *b, size_t length )
{
  assert( b != NULL );

  if( b->memory == NULL or length > b->length )
    return( 0 );

  return( 1 );
}

void *buffer_get( struct buffer *b )
{
  assert( b != NULL );

  return( b->memory );
}

Use the API and not malloc/free and you can't go wrong.



回答6:

sizeof is used to calculate size for actual objects, not pointers for objects in memory. It returns size of structs or primitives. I mean it will work, but will give you size of the pointer, not the structure it points to. To get the length of any sort of array use :

strlen(buffer)