简体   繁体   中英

Confusion with malloc

I'm trying to understand a piece of C code which is as follows:

#define DIM2( basetype, name, w1 ) basetype (*name)[w1]
int mx = 10; //number of rows per processor
int my = 100; //number of cols
DIM2 (double, f, my);
f = (typeof (f)) malloc (2 * mx * sizeof (*f));

If I'm correct, with DIM2 a 1-d array of (size=100) pointers to double is created. I'm not able to understand what happens again with malloc? Is it necessary for two such statements?

Is there any alternative way to achieve what happens in the last two lines of code above in any other way?

The macro evaluates to:

double (*f)[my];

which is a pointer to array of double , not an array of pointer to double .

malloc allocates an array of 2 * mx * <whatever f points to> (ie an array of double). Not sure why it would allocate twice as many entries as given by mx , but that's what it does.

So, f points to the first array of double afterwards. It effectively allocates a true 2 dimensional array. (not the often confused array of pointers to double ).

Note that the cast of malloc is bad practise in C.

Comment: As there is not less typing and the macro does not add specific information, it is actually bad practise. Worse is it hides the pointer semantics obfuscating the code. Recommendation is not to use it, but better be explicit; this is even not more typing.

Update: There is currently an argument if sizeof(*f) presents _undefined behaviour , because f` is used uninitialized here. While I see a flaw in the standard here which should be more precise, you might better play safe and use an explicit expression:

f = malloc (2 * mx * my * sizeof (double))

double (*f)[my] is a VLA type because my is an int . So sizeof (*f) causes undefined behaviour because the argument of sizeof is evaluated if it has VLA type. For more discussion see here .

Unfortunately the sizeof *f idiom can only be used with pointer to array of fixed dimension (or pointer to non-array!). So this entire idea is bogus.

IMHO it is simpler and clearer to do away with the macro and write:

double (*f)[my] = malloc( sizeof(double[mx][my]) );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM