Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allocating less space then necessary for a certain type?

I am relatively new to C programming and having a hard time understanding the whole memory allocation issue.

Let's say, I do:

int *n = malloc(sizeof(char));
// (assuming malloc doesn't return NULL of course)

That provides a Pointer to int, but I didn't allocate enough memory for an int. Why does it work then? I could even cast it to int explicitly and it wouldn't bother gcc. I am aware of C compilers being very minimalist, but even if I assign a value to *n, which doesn't fit in a char, like:

*n = 300;

... and print it out afterwards:

printf("%d", *n);

... it works perfectly fine, although now at the latest I'd expect some error like a segmentation fault.

I mean, sizeof(char) is 1 and sizeof(int) is 4 on my machine. Hence 3 bytes are written to some place in memory which hasn't been allocated properly.

Does it work just because it doesn't leave the stack?

Could somebody please point me to a place where I might find enlightenment concerning that stuff?

like image 504
Aramís C. D. Avatar asked Oct 23 '11 19:10

Aramís C. D.


People also ask

How do you allocate space in a string?

Space is allocated by calling malloc with the number of bytes needed (for strings this is always one more than the maximum length of the string to be stored): char *pc = malloc(MAXSTR + 1) ; // can hold a string of up to MAXSTR characters.

How do you allocate a block of memory?

Blocks of memory allocated on the heap are actually a special type of data structure consisting of (1) A pointer to the end of the previous block, (2) a pointer to the end of this block, (3) the allocated block of memory which can vary in size depending on its use, (4) a pointer to the beginning of this block, and (5) ...

What is size & Space allocation?

In fixed-size allocation, the storage space in a disk drive is partitioned into blocks of one single size. The host system to which the disk drive is attached allocates disk space by such fixed-size blocks. As many blocks as necessary are allocated to store a user file or record.

What is fixed-size block allocation?

Fixed-size blocks allocation, also called memory pool allocation, uses a free list of fixed-size blocks of memory (often all of the same size). This works well for simple embedded systems where no large objects need to be allocated, but suffers from fragmentation, especially with long memory addresses.


1 Answers

That provides a Pointer to int, but I didn't allocate enough memory for an int. Why does it work then?

The return value from malloc is void*, the language allows this to be implicitly converted to any pointer type, in this case int*. Compilers don't typically include behavior to check that what you passed to malloc met a specific size requirement, in real-world code that can be very difficult (when non-constant sizes not known at compile time are passed to malloc). As you said, C compiler are usually rather minimalist. There are such things as "static analysis" tools which can analyze code to try to find these bugs, but that's a whole different class of tool than a compiler.

... it works perfectly fine, although now at the latest I'd expect some error like a segmentation fault. I mean, sizeof(char) is 1 and sizeof(int) is 4 on my machine. Hence 3 bytes are written to some place in memory which hasn't been allocated properly.

Writing beyond the bounds of allocated memory is what is called "undefined behavior". That means that a compliant compiler can do whatever it wants when that happens. Sometimes it will crash, sometimes it can write over some other variable in your program, sometimes nothing will happen, and sometimes nothing will seem to happen and your program will crash at a later date.

In this particular case what is happening is that most implementations of malloc allocate a minimum of 16 bytes (or more or less, like 8 or 32) even if you ask for less. So when you overwrite your single allocated byte you're writing into "extra" memory that was not used for anything. It is highly not recommended that you rely on that behavior in any real program.

Does it work just because it doesn't leave the stack?

The stack has nothing to do with this particular situation.

Could somebody please point me to a place where I might find enlightenment concerning that stuff?

Any good C book will have information of this type, take a look here: The Definitive C Book Guide and List

like image 119
SoapBox Avatar answered Sep 27 '22 16:09

SoapBox