Allocating memory with an undefined pointer

I was surprised when gcc -Wall compiled this without warning. Is it legal C? What are the risks of writing such code?

 #include <stdio.h> #include <stdlib.h> typedef struct { int a; int b; } MyStruct; int main(void) { MyStruct *s = malloc(sizeof(*s)); // as opposed to malloc(sizeof(MyStruct)) s->a = 5; printf("%d\n", s->a); } 
+6
source share
3 answers

sizeof is evaluated at compile time. In this context, *s resolves to type *s ; it does not look up a pointer.

This is the canonical way of using sizeof . If you used sizeof(int) , you leave a hole for the error if the type is changed (in this case, it is probably unlikely, but still.)

+2
source

Not only is this legal, but also preferable to alternatives. This way you let the compiler infer the actual type instead of doing it manually.

+5
source

Record

 MyStruct *s = malloc(sizeof(*s)); 

has the same effect as

 MyStruct *s = malloc(sizeof(MyStruct)); 

except that now you only write MyStruct once. That is, the object that you select has a source type that is automatically detected, which reduces the likelihood of errors.

For example - it happened to me - you start with MyStruct . Then you decide that you need different MyStruct for different purposes. Thus, you get two different structures: MyStruct and AnotherStruct .

Then you reorganize your code and change some variables from MyStruct to AnotherStruct , and in the end

 AnotherStruct *s = malloc(sizeof(MyStruct)); 

which could work in several circumstances or for a long time, until you do a little more, and at that moment changes in any structure are not completely connected. At this point, your code goes into kaboom.

eg.

 typedef struct { int a; int b; } StructA; typedef struct { int a; int b; int c; } StructB; int main() { // No problem here except wasted space StructA *s = malloc(sizeof(StructB)); // t->c dwells in undefined country StructB *t = malloc(sizeof(StructA)); } 
+1
source

All Articles