Imagine I've the following struct
struct Memory {
int type;
int prot;
};
typedef struct Memory *Memory;
How would I initialise it using malloc()?
Memory mem = malloc(sizeof(Memory));
or
Memory mem = malloc(sizeof(struct Memory));
What is the correct way to allocate that?
This construction
defines an object with name
Memory
that has type of unnamed structure.Thus the next construction
defined 1) a new type
struct Memory
that has nothing common with the definition above and the name Memory. and 2) another new type nameMemory
that is pointer tostruct Memory
.If the both constructions are present in the same compilation unit then the compiler will issue an error because name
Memory
(the name of the pointer) in the typedef declaration tries to redeclare the object of the type of the unnamed structure with the same nameMemory
.I think you mean the following
In this case you may use the both records of using malloc like
and
or
or
because now the two identifiers Memory are in two different name spaces, The first one is used with tag
struct
and the second is used without tag struct.Both
and
are wrong. The correct way to do it is :
or
The name of the structure should be different than the name of a pointer to it.
Your struct declaration is a bit muddled up, and the typedef is wrong on many levels. Here's what I'd suggest:
Then allocate like so:
Read the
malloc
call like so: "Allocate the amount of memory required to store whatever typemem
is pointing to". If you changeMemory *mem
toMemory **mem
, it'll allocate 4 or 8 bytes (depending on the platform), as it now stands it'll probably allocate 8 bytes, depending on the size ofint
and how the compiler pads the struct check wiki for more details and examples.Using
sizeof *<the-pointer>
is generally considered to be the better way of allocating memory, but if you want, you can write:They all do the same thing. Mind you, if you
typedef
a struct, that's probably because you want to abstract the inner workings of something, and want to write an API of sorts. In that case, you should discourage the use ofstruct _memory
as much as possible, in favour ofMemory
or*<the-pointer>
anywayIf you want to
typedef
a pointer, then you can write this:In which case this:
might seem counter intuitive, but is correct, as is:
But this:
is wrong (it won't allocate the memory required for the struct, but memory to store a pointer to it).
It's a matter of personal preference, perhaps, but I personally find
typedef
s obscure certain things. In many cases this is for the better (ieFILE*
), but once an API starts hiding the fact you're working with pointers, I start to worry a bit. It tends to make code harder to read, debug and document...Just think about it like this:
The
*
operator modifies a variable of a given type, a pointer typedef does both. That's just my opinion, I'm sure there are many programmers that are far more skilled than me who do use pointer typedefs.Most of the time, though, a pointer
typedef
is accompanied by custom allocator functions or macro's, so you don't have to write odd-looking statements likeMemory_p mem = malloc(sizeof *mem);
, but instead you can writeALLOC_MEM_P(mem, 1);
which could be defined as:or something