Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Malloc -> how much memory has been allocated?

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

int main ()
{
  char * buffer;
  buffer = malloc (2);

  if (buffer == NULL){
    printf("big errors");
  }
  strcpy(buffer, "hello");
  printf("buffer is %s\n", buffer);
  free(buffer);
  return 0;
}

I allocated 2 bytes of memory to the pointer/char buffer yet if I assign the C-style string hello to it, it still prints the entire string, without giving me any errors. Why doesn't the compiler give me an error telling me there isn't enough memory allocated? I read a couple of questions that ask how to check how much memory malloc actually allocates but I didn't find a concrete answer. Shouldn't the free function have to know exactly how much memory is allocated to buffer?

like image 500
penguinsource Avatar asked Mar 06 '11 20:03

penguinsource


People also ask

How much memory is allocated by malloc?

The malloc() function reserves a block of storage of size bytes. Unlike the calloc() function, malloc() does not initialize all elements to 0. The maximum size for a non-teraspace malloc() is 16711568 bytes.

How do we find the size of memory allocated using malloc?

Syntax: ptr = (cast-type*) malloc(byte-size) For Example: ptr = (int*) malloc(100 * sizeof(int)); Since the size of int is 4 bytes, this statement will allocate 400 bytes of memory.

How many bytes does malloc 10 allocate?

malloc(10) allocates 10 bytes, which is enough space for 10 chars. To allocate space for 10 ints, you could call malloc(10 * sizeof(int)) . char *cp = malloc(10); int *ip = malloc(sizeof(int));

How many bytes will malloc 4 allocate?

The malloc line allocates a block of memory of the size specified -- in this case, sizeof(int) bytes (4 bytes). The sizeof command in C returns the size, in bytes, of any type. The code could just as easily have said malloc(4), since sizeof(int) equals 4 bytes on most machines.


3 Answers

The compiler doesn't know. This is the joy and terror of C. malloc belongs to the runtime. All the compilers knows is that you have told it that it returns a void*, it has no idea how much, or how much strcpy is going to copy.

Tools like valgrind detect some of these errors. Other programming languages make it harder to shoot yourself in the foot. Not C.

like image 109
bmargulies Avatar answered Sep 28 '22 02:09

bmargulies


No production malloc() implementation should prevent you from trying to write past what you allocated. It is assumed that if you allocate 123 bytes, you will use all or less than what you allocated. malloc(), for efficiency sake, has to assume that a programmer is going to keep track of their pointers.

Using memory that you didn't explicitly and successfully ask malloc() to give you is undefined behavior. You might have asked for n bytes but got n + x, due to the malloc() implementation optimizing for byte alignment. Or you could be writing to a black hole. You never can know, that's why it's undefined behavior.

That being said ...

There are malloc() implementations that give you built in statistics and debugging, however these need to be used in lieu of the standard malloc() facility just like you would if you were using a garbage collected variety.

I've also seen variants designed strictly for LD_PRELOAD that expose a function to allow you to define a callback with at least one void pointer as an argument. That argument expects a structure that contains the statistical data. Other tools like electric fence will simply halt your program on the exact instruction that resulted in an overrun or access to invalid blocks. As @R.. points out in comments, that is great for debugging but horribly inefficient.

In all honesty or (as they say) 'at the end of the day' - it's much easier to use a heap profiler such as Valgrind and its associated tools (massif) in this case which will give you quite a bit of information. In this particular case, Valgrind would have pointed out the obvious - you wrote past the allocated boundary. In most cases, however when this is not intentional, a good profiler / error detector is priceless.

Using a profiler isn't always possible due to:

  • Timing issues while running under a profiler (but those are common any time calls to malloc() are intercepted).
  • Profiler is not available for your platform / arch
  • The debug data (from a logging malloc()) must be an integral part of the program

We used a variant of the library that I linked in HelenOS (I'm not sure if they're still using it) for quite a while, as debugging at the VMM was known to cause insanity.

Still, think hard about future ramifications when considering a drop in replacement, when it comes to the malloc() facility you almost always want to use what the system ships.

like image 38
Tim Post Avatar answered Sep 28 '22 02:09

Tim Post


How much malloc internally allocates is implementation-dependent and OS-dependent (e.g. multiples of 8 bytes or more). Your writing into the un-allocated bytes may lead to overwriting other variable's values even if your compiler and run-time dont detect the error. The free-function remembers the number of bytes allocated separate from the allocated region, for example in a free-list.

like image 37
Bernd Elkemann Avatar answered Sep 28 '22 04:09

Bernd Elkemann