Question about memory allocation in C

Hello i was wondering if it is possible to get the size of some dynamicaly allocated memory like Bmem here.


1
2
3
4
5
void *Bmem = malloc(50000);

char *Pixel = (char*)Bmem;

int BmemSize = sizeof((char*)Bmem) * 50000; <--- (=400000)


And is it dangerous to iterate over a larger size than given back by malloc like this?

like writing to 1 beyond the memory allocated.

1
2
3
4
5
6
	for(int i  = 0;
		i < 400001;
		i++)
	{
		printf("%c", *Pixel++);
	}


i dont seem to get any errors and it does work

Edited by C_Worm on Reason: Initial post
You ask malloc for an amount of memory, so you already know the size.

Having said that, malloc will have internal housekeeping to track memory blocks and sizes, but there's no way to access that housekeeping data.

If you want a way to keep the allocated amount next to the pointer, take a look at Sean Barrett's stretchy buffer implementation, in which the capacity and element count of the array are stored right before the array.

When doing this: int BmemSize = sizeof((char*)Bmem) * 50000; <--- (=400000), what you're computing is [m]sizeof(char*) * 50000[\m], which in a 64bit architecture will result in 8 * 50000. This [m]sizeof[\m] won't return the size of the allocation.

You can write past the end of the array because at the OS level, memory allocation granularity is at the page size (e.g. 4KB, 2MB, 1GB), so even if malloc gives you a 2KB block of memory, you can write past the end of the array without a memory protection fault.

Casey does a more detailed explanation in Handmade Hero while implementing the memory arena.
If you are OK using OS specific functions, then you can use _msize (MSVC), malloc_usable_size (Linux), or malloc_size (macOS).
Although, as already marcc mentions - if you are calling malloc, then you already know the size. Use the same value as you passed to malloc. Either as global constant, or store it somewhere and pass to code that needs it.

Edited by Mārtiņš Možeiko on
If you are OK using OS specific functions, then you can use _msize (MSVC), malloc_usable_size (Linux), or malloc_size (macOS).


Thanks, mmozeiko! TIL :)
I think you have got everything backwards

Malloc takes the number of bytes you need allocated so bMem contains 50,000 bytes

You then cast this to a char* which is 8 bytes on 64bit. This means the number of *pixels that can be stored is (50000 / 8) which is 6250 not the 400000 you get when you multiply instead

Inside your loop pixel++ will increment by 8 bytes so you will get a buffer overflow once i gets to 6251

If you where after 50000 pointers then you should use malloc(50000 * sizeof(char*))

Regards,
John.