Sign in to follow this  
AsOne

malloc question

Recommended Posts

Can somone please tell me why this works?
#include <stdio.h>
#include <stdlib.h>

typedef struct _vertex
{
    float x;
    float y;
    float z;
} Vertex;

int main()
{
    Vertex *vertex = malloc(sizeof(Vertex));
    vertex->x = 10;
    vertex->y = 20;
    vertex->z = 30;
    printf("x = %f, y = %f, z = %f\n", vertex->x, vertex->y, vertex->z);
    printf("the memory allocated for the vertex data is %d bytes.\n", sizeof(vertex));
    printf("shouldn't the above be %d bytes?\n", sizeof(Vertex));
    free(vertex);
    return 0;
}



First it prints that the vertex is 4 bytes in size, but the size of the Vertex struct is 12 bytes (which it should be). I've also changed
malloc(sizeof(Vertex))
to
malloc(0);
and it worked perfectly fine. Is my compiler automatically 'fixing' this? This seems very odd to me.

Share this post


Link to post
Share on other sites
sizeof(vertex) will give you the size of the pointer, not the size of the object pointed to. Use sizeof(*vertex) to get the size of the pointed-to object.

malloc is allowed to treat zero-byte requests as a request for some non-zero number of bytes, however you are not allowed to access the allocated memory. Basically you're writing to semi-random memory that probably just happens to be valid from the operating-systems point of view, just like if you were overwriting the bounds of an array. Don't do it!

Enigma

Share this post


Link to post
Share on other sites
The variable vertex is a pointer .. what it points to , who cares ? you are just telling the compiler and yourself that it points to a structure Vertex (which is 12 bytes). All pointers with 32 bit compiler are 4 bytes, which is simply storage for a memory address.

if malloc(0) worked then I am assuming that you are assigning values with a bad pointer (no pointer). You would eventually crash your program if you continue to access memory that you have not allocated.

*** Edit

Enigma beat me to it lol :)

Share this post


Link to post
Share on other sites
Quote:

sizeof(vertex) will give you the size of the pointer, not the size of the object pointed to. Use sizeof(*vertex) to get the size of the pointed-to object.

Silly me, I should have realized that :S

So it was luck then that malloc(0) returned a location which was valid?

Share this post


Link to post
Share on other sites
Quote:
Original post by AsOne
So it was luck then that malloc(0) returned a location which was valid?

It wasn't a valid location. Using that memory had undefined behaviour. It just so happens that sometimes undefined behaviour means it seems to work.

Enigma

Share this post


Link to post
Share on other sites
No, malloc(0) is perfectly legal. You will be give a valid pointer to a 0-byte piece of memory that is guaranteed to be unique relative to any other malloc(0). It's no different than a malloc of any other size. When you're done with it you have to call free on it. Since it's 0 bytes you can't actually use the pointer for anything. Trying to will give you undefined behavior exactly like going off the end of an array will.

There are a couple reasons why it works. The first is that it makes things a little simpler for the caller. The second is that internally malloc has to attach some bookkeeping information anyway so your malloc(0) gets turned into _internal_malloc(0 + sizeof(bookkeeping_info)).

Share this post


Link to post
Share on other sites
Anon Mike: According to the final draft of the C99 standard the behaviour of malloc on zero-byte allocation requests is implementation defined. Implementations are allowed to behave as you say, but they are also allowed to simply return a null pointer.

Enigma

Share this post


Link to post
Share on other sites
Quote:
Original post by Anon Mike
No, malloc(0) is perfectly legal. /snip/


You might be thinking about new in C++, which requires that the return value for operator new(0) is a non-null value.

Share this post


Link to post
Share on other sites
Just to clarify, when I said that the return value of malloc(0) "wasn't a valid location" I didn't mean it wasn't a valid pointer - it may or may not have been. What I meant was that it was not a valid chunk of memory in which you could store a vertex.

Enigma

Share this post


Link to post
Share on other sites
Quote:
Original post by Enigma
Anon Mike: According to the final draft of the C99 standard the behaviour of malloc on zero-byte allocation requests is implementation defined. Implementations are allowed to behave as you say, but they are also allowed to simply return a null pointer.

Ah ok. My C is a bit rusty and my compiler doesn't support C99 anyway, although it does return a valid pointer for malloc(0).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this