THE PARADOX
THE PARADOX

Reputation: 29

cannot understand why malloc function in c is doing as explained below?

When i wrote the following code i got weird answers.

#include<stdio.h>
#include<stdlib.h>
main()
{
int *p=malloc(1);
if(p==0)
printf("memory not assigned\n");
else
{
printf("memory assigned\n");
printf("enter an int\t");
scanf("%d",p);
printf("\n You entered number %d",*p);
printf("\nIt has been stored at-%p",p);
}
}

I think malloc takes argument as number of byte.so here i entered 1 byte and i know that on my machine int requires 4 bytes for storage(through sizeof()) but still the code shows no error and i can enter an int value.even if i enter 3333333 it does not complain.if i use malloc() instead of malloc(1) gcc complains of too few argument for malloc but still gives the same result.I cant understand this behaviour.will someone please clarify it.

I am running it on gcc through virtual box.

Upvotes: 1

Views: 1235

Answers (5)

Aki Suihkonen
Aki Suihkonen

Reputation: 20027

Malloc in "modern" environments use different kind of allocation strategies for different lengths. The common thing is that in 32-bit environments the de facto standard was to align everything by 8 bytes and nowadays in x64 era in 16-byte granularity.

This in effect means there are 7 or 15 characters of extra space after the 1 byte you asked. Should you use it? Only with consenting adults within closed doors.

Among the methods, btw, there are reverting to system call, that allocates pages at physical boundaries -- try e.g. malloc(1<<28); (256 Mb); some implementation of malloc allocate 1-8 or 1-16 bytes from a special buffer and in turn for larger chunks reserve internally N+8 or N+16 (again rounded up to next boundary) for bookkeeping data too.

This is the data that will be trashed, if you overwrite your reserved area. It leads to ASSERT in some malloc / free later on and it leads to a duplicate and soon to be closed very vague question on SO.

Malloc on embedded systems can be programmed not to be able to reclaim; it can be implemented simply by

void *malloc_embedded(size_t a) {
    static uint8_t *heap=_heap;
    uint8_t *old=heap; heap+=a;
    return old;
}

This behaves as you probably expected, but the use cases are much more limited -- this method could be modified to be able to free the last allocated element but no more.

Upvotes: 2

ldav1s
ldav1s

Reputation: 16305

The implementation of malloc is unlikely to give you exactly one byte. It'll likely be sized up to the nearest word size, which means that something that is the sizeof(int) will fit into that space. Much like:

struct foo {
    char a;
};

The sizeof(struct foo) will likely be the word size. Needless to say, you should be allocating more space (e.g. malloc(sizeof(int))) since you want to read an int. It'll be less confusing for software maintenance later on, despite the fact it "happens" to work. It's likely undefined behavior.

Upvotes: 0

user2088639
user2088639

Reputation:

As you said, if you do this:

int *p=malloc(1);

Only 1 byte will be allocated. Since an int is larger than 1 byte, it will overrun the allocated memory and give you undefined behavior. If you do this:

int *p=malloc(sizeof(int));

Then there will be enough space for the integer.

C does not warn you when you run outside the bounds allocated memory, so you need to carefully manage what size you malloc.

Upvotes: 3

Krishnabhadra
Krishnabhadra

Reputation: 34265

It is your responsibility to alloc enough memory for your needs. Compiler won't check whether you are accessing memory which is outside what you alloc'ed.

If you alloc x amount of memory, to store values of size grater than x, your app may(may not) crash at run time. It is undefined behaviour.

If you call malloc(1) ,there is no need for the compiler to complain since, malloc requires one argument (size of memory), and you are passing it..

But when you call malloc(), the case is different, and compiler complains..

Upvotes: 0

Aniket Inge
Aniket Inge

Reputation: 25695

Undefined behavior ?? malloc(1) returns a free block or size 1 byte, there might be more blocks besides the one returned, where your integer gets written.(that rhymed!)

Obviously, malloc() requires 1 argument. If you supply none, gcc will complain, and so will all other compilers that obey C's standard.

If you want sizeof(int) bytes then: malloc(sizeof(int))

Upvotes: 0

Related Questions