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

int main(void)
{
  char * ptr1 = NULL;
  char * newptr = NULL;

  ptr1 = (char *) malloc(8 * sizeof(int));
  if (ptr1 == NULL)
    exit(EXIT_FAILURE);

  printf("%p\n", ptr1);

  newptr = ptr1 - sizeof(size_t);
  printf("%zu\n", (*(size_t *)newptr));
  free(ptr1);

  return 0;
}

Output :

0x...... [some address]
49

49 - 1 = 48 - (8 * 4) = 16

Assuming sizeof(int) = 4

According to the glibc malloc() implementation the maximum overhead per chunk is 8 bytes

but size of this chunk field gives 48 subtracting the usable memory gives 16. So the overhead is showing 16 bytes. I know something is going wrong but I can't figure it out where I doing the wrong calculation.

Please help. Thank you.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
arka
  • 418
  • 2
  • 9
  • 3
    There is no portable, reliable way to find out the size of the block of memory allocated by `malloc()` et al from a pointer to the memory. There also isn't a portable, reliable way to find the start of the allocated block given a pointer to somewhere within that block. – Jonathan Leffler Apr 06 '22 at 13:16
  • On most 64bit platforms, malloc has to return an address aligned on 16 bytes. This means that the allocated size + overhead will usually be rounded up to a 16 bytes multiple. – ElderBug Apr 06 '22 at 13:21
  • Two things that you already know though: 1) You know the size of memory requested. and 2) if call to `malloc` was successful, it is guaranteed that the size of memory allocated is `>=` to the size of memory requested. (alignment implementations may result in a little more than asked for.) – ryyker Apr 06 '22 at 13:23
  • @JonathanLeffler I know that it is not a portable solution to know the memory chunk size. I am only doing from the perspective of my machine architecture. – arka Apr 06 '22 at 13:23
  • 2
    Curious, then, that you don't mention which machine you're working with. If you are interested in an implementation-specific solution (one that depends on a specific implementation of `malloc()` and friends), then say so, and say which implementation. You tag [tag:glibc] but that's the sort of random tag that appears on questions for no obvious reason. You should explicitly call it out in the body of the question if that's what you're interested in. – Jonathan Leffler Apr 06 '22 at 13:26
  • 1
    By the way, it it [not necessary to cast](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) the return of `malloc()` in `C`. `ptr1 = malloc(8 * sizeof(int));` is sufficient. ([another](https://stackoverflow.com/a/7545391/645128) short simple reason.) – ryyker Apr 06 '22 at 13:31
  • The expression `ptr1 - sizeof(size_t)` invokes undefined behavior – klutt Apr 06 '22 at 13:37
  • 1
    Re "*I am only doing from the perspective of my machine architecture*", So you looked at your compiler's source code to see its implementation of `malloc`, then. What did you find? What are you having problems understanding? Why didn't you share a link to this code? Why didn't you mention which compiler and OS you're using? – ikegami Apr 06 '22 at 13:39
  • That doesn't answer ANY of the questions I raised. – ikegami Apr 06 '22 at 13:45
  • @arka What a strange question. The behavior is undefined which means we cannot say what the behavior is. – klutt Apr 06 '22 at 13:58
  • Asking _"what undefined behavior is invoked"_ is both funny, and unanswerable. After all, it is _undefined_ – ryyker Apr 06 '22 at 14:01
  • @klutt Re "The expression ptr1 - sizeof(size_t) invokes undefined behavior". It doesn't invoke any undefined behavior. It is simply the pointer arithmetic and it is sure that the pointer is not **NULL** at the point of the arithmetic. – arka Apr 06 '22 at 14:21
  • @arka Where does the pointer `ptr1 - sizeof(size_t)` point? – klutt Apr 06 '22 at 14:23
  • *"Pointing to a location doesn't mean the undefined behavior till you know what you are doing."* - Wrong ;) – klutt Apr 06 '22 at 14:33

1 Answers1

2

This is one of those implementation-defined things that you shouldn't mess with except for experimentation or research purposes.

In GNU platforms a function exists in a non-C-standard header malloc.h called malloc_usable_size() which will tell you the actual byte-length of your malloc()ed chunk of heap given some pointer that is the return value of malloc() but in its own documentation it says "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."

According to the C-standard, the chunk of memory allocated by malloc() is only guaranteed to be as many bytes as you ask for, but in practice most, if not all, implementations give you a little extra for padding or the purposes of the memory manager. I remember a computer science professor of mine demonstrating how you could look at the memory right before the pointer passed from malloc() on her system just like you are doing to read information about the chunk of memory, but the C programming language does not require malloc() to be implemented this way nor does it guarantee how any such data would be encoded.

It seems you're using GNU, so if you want to learn more about how malloc() is implemented on your platform take a peek at malloc_usable_size() and see if it really is giving you 48 bytes when you asked for 32. For the record I wouldn't be at all surprised if it is.

I'm not sure what you're referring to when you say the maximum overhead is 8-bytes in glibc. That might mean that the maximum memory used by the heap manager for each chunk is 8-bytes, not including extra memory allocated for alignment?

Willis Hershey
  • 1,520
  • 4
  • 22
  • Re “in its own documentation it says it's purely for debugging and should not be used in production code”: No, it does not. It says “The main use is for debugging and introspection.” It does not say at all that it should not be used in production code. – Eric Postpischil Apr 06 '22 at 13:45
  • That's a fair point. Writing outside the asked size in the malloced region is *not good programming practice* but using the function itself is not explicitly discouraged. I made the edit. – Willis Hershey Apr 06 '22 at 13:50
  • Lots of wiggly statements here. _"I'm not sure ..."_, _"That might mean ..."_, _"It seems you're using ..."_, ...Really qualifies as an extended comment. I'm not sure if there is an answer somewhere in there. Can you point it out? – ryyker Apr 06 '22 at 14:08
  • 1
    The question was how do I find the length of a chunk, I answered the question. "take a peek at `malloc_usable_size()`" – Willis Hershey Apr 06 '22 at 14:09