Question:
C program help: Insufficient memory allocation but still works...why?
Martin
2013-01-31 13:26:23 UTC
I allocated 0 bytes for this pointer but it can still hold an integer. As a matter of fact, no matter what number I put into the parameter of malloc, it can still hold any number I give it. Why is this?

#include
#include

int main(void)
{
    int *ptr = (int*)malloc(0);

    *ptr = 9;

    printf("%i", *ptr); // 9

    free(ptr);

    return 0;
}

It still prints 9, what's up with that?
Five answers:
Jared
2013-01-31 14:31:17 UTC
The reason this worked (and this is somewhat of a guess) is that when you run your program the OS allocates a page of memory to your program. This is such a small program that the program stack isn't going to take up a whole lot of space, so there is PLENTY of room left on your page of memory (which is probably a few mega bytes). When you call malloc, it's going to retrieve a memory location somewhere in this page (but definitely NOT on the stack--it will be on the heap which is always separate from the stack).



So, you got a "good" memory location and thus can write to it. This is opposed to a "bad" memory location (like if you hadn't initialized the pointer) which means the memory points to somewhere off of your program's page and thus would cause a segfault. There's nothing unsafe about that because your OS doesn't allow your program to write to stuff it's not supposed to...now, you CAN overwrite things like the stack which can cause strange behavior, but this isn't going to happen with malloc. But if you did something like you added to the pointer (or subtracted...depending on the layout), you COULD get into the stack and cause problems.





I am interested to see what would happen if you did something like this:



int *ptr1 = malloc(0);

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



*ptr1 = 9;

*ptr2 = 10;



printf("ptr1 is %d and ptr2 is %d\n", *ptr1, *ptr2);



free(ptr1);

free(ptr2);





My suspicion is that ptr1 and ptr2 will point to the same memory location (in the heap) and thus they would both end up being 10 in this case. If you did something like allocated say 1 or 2 bytes the first time, it may or may not do something even weirder.





Edit:



I tried that, it didn't work and here's why: http://linux.die.net/man/3/malloc



"If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free()."



So, when you put in 0, apparently you are getting a unique pointer value (i.e. a valid one).
Richard
2013-01-31 23:29:21 UTC
C itself does not check that you are sticking within the memory space allocated to an array or by malloc. It relies on the operating system to protect other programs if you address memory outside the space allocated to a program.



For example:



int a[100],b[4],c[100];



will allocate 3 integer arrays of the sizes shown.



You can then have a loop that says:



for (x = 0;x < 12;x++)

b[x] = x;



The loop will overwrite the four locations in the 'b' array, but will also overwrite 8 locations in another array. This will most likely be the first 8 locations of the 'c' array.



When you allocate memory space with malloc, you get a pointer to the start of that space. It is up to you to make sure you do not run off the end of the allocated space or you may corrupt other variables. If you go to far, you will run out of the space the operating system has allocated to the program and an exception error will occur.
Michael
2013-01-31 22:31:49 UTC
Hello,



This one can be a little technical.



malloc(0) may return null or a non-null value depending on the implementation. In other words, its implementation defined and the result is malloc(0) is not defined by the standard. In both cases however the address returned should not be dereferenced.



case 0: malloc(0) returns null

I'll ignore this case since Windows uses the following case. This you can verify yourself using a debugger.



case 1: malloc(0) returns non-null (acts like malloc(size) where size is implementation defined)

This would return some valid address allocated on your program heap. The program heap is preallocated by the operating system and so is valid memory that you can read/write from.



In conclusion, it works because malloc(0) is returning a valid address on the heap. It is really dangerous though because it is allocating an implementation-specific size and may corrupt further memory allocations if not careful. The address is valid and so can be written to and dereferenced.



Note this information is specific to Windows NT systems as implementation details can differ between operating systems and architecture.
2013-01-31 23:17:16 UTC
malloc 0 gets a million hits on google
petrolhead
2013-01-31 21:36:39 UTC
when you point to something, your pointing to its memory location, not its value.

pointer notation is horrible to use and understand.

You need to be really clear that what you think you are pointing to is definitely what your pointing to.

I have been told to avoid this type of programming by my professor because it is not safe, i.e. you can wreck a computer if you touch memory used for something else i.e. OS.



I suggest you take a look at cplusplus.com it explains pointers very well with examples, and C++ is based on C.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...