-1

In a header file -- gameboard.h -- I have a struct named gameboard. In this struct I declare square **squares, where squares is the following: typedef enum {EMPTY, RED_COIN, YELLOW_COIN} square;

In gameboard.c, I have a function that allocates memory for a 2D array. In this function I declare gameboard* result.

Question: When creating the initial array, i.e. the part of a 2D that will store an array, why can't I do this:

result->squares = malloc(numRows * sizeof(result->square*));

More specifically, why is square an invalid type?

DYZ
  • 55,249
  • 10
  • 64
  • 93
darylnak
  • 239
  • 4
  • 14
  • If `square` is a type name, then what are you trying to say by `result->square`? This just does not make any sense in C. In C `->` is a *member access* operator. And your struct does not have a member named `square`. – AnT stands with Russia Mar 01 '17 at 02:51
  • Something like `anytype **` is no 2D array, nor can it point to one! And you should read [ask] and provide a [mcve]. – too honest for this site Mar 01 '17 at 03:08

1 Answers1

3

You cannot "do this" because your result->square subexpression is invalid. result->squares would be valid. Plain square would be valid too. But result->square makes no sense at all. In C -> is a member access operator. And your struct type does not have a member named square.

  • A typical/idiomatic C code for malloc-ing an array of objects would look as follows

    some_pointer = malloc(n_elements * sizeof *some_pointer);
    

    Applying this to your case we get

    result->squares = malloc(numRows * sizeof *result->squares);
    
  • If your result->squares has type square **, then the proper size can also be expressed in terms of sizeof(array_element_type) as

    result->squares = malloc(numRows * sizeof(squares *));
    

    But the former (type-agnostic) variant is arguably better than this latter version, specifically for being type-agnostic. See also: Why is it safer to use sizeof(*pointer) in malloc

How you managed to arrive at sizeof(result->square*) is completely unclear to me. Your variant looks like a bizarre hybrid of the two, written in incorrect and meaningless way.

Community
  • 1
  • 1
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Also, gameboard.squares is declared as an array of pointer of square. I am not sure if this is the intent. – KC Wong Mar 01 '17 at 02:42
  • @AnT: My class is currently going over pointers and structs and it's apparent there are gaps in my knowledge. After reviewing your comment and my question, I see the many errors made before posting. My next question would be the difference between using malloc() for a 2D array of ints and my case. For example, I would do this for ints: somePtr = malloc(sizeof(int*) * numElements). When dealing with structs, why use squares instead of it's type (square)? – darylnak Mar 01 '17 at 02:43
  • @KC Wong: The OP stated that the ultimate objective is to create a 2D array. Assuming they are after a typical "jagged array" approach, seeing `squares` declared as a "pointer to pointer" does not looks strange at all. – AnT stands with Russia Mar 01 '17 at 02:44
  • @darylnak: `sizeof` has two forms: you can use a *type name* under `sizeof` or you can use an *expression* under `sizeof`. My answer above shows both variants in context of your `malloc`. Both variants will work. However, I would argue for the first - type-independent (or type-agnostic) - variant. See also http://stackoverflow.com/questions/17258647/why-is-it-safer-to-use-sizeofpointer-in-malloc – AnT stands with Russia Mar 01 '17 at 02:48
  • @AnT Thank you, I understand now! I may have to look over the text-book again. I did not know I could do this. – darylnak Mar 01 '17 at 03:10