malloc question

Started by
9 comments, last by Anon Mike 18 years, 7 months ago
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.
Advertisement
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
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 :)
-------------Become part of developing the specifications of a new language. Visit CodeBASIC.org
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?
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
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)).
-Mike
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
Thanks for the replies :)
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.
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

This topic is closed to new replies.

Advertisement