-1

I am trying to access a field from a struct through a pointer of pointer

I tried:

(**vform).vpolygon->point->x = 1;                                               

But doesn't worked.

code:

typedef struct point{
    int x;
}point;
typedef struct polygon{
    point *point;
}polygon;
typedef struct form{
    polygon **polygon;
}form;
void main(){
      polygon *vpolygon;
      form **vform;
      vpolygon = (polygon *)malloc(sizeof(polygon)*5);
      vform = (form **)malloc(sizeof(form)*5);
      vpolygon->point->x = 1;
      vform->vpolygon->point->x = 1;
}

I expect the program compile, but the actual output is

18:12: error: '*vform' is a pointer; did you mean to use '->'?
       vform->vpolygon->point->x = 1;
            ^~
            ->
Prot
  • 1
  • 3
  • 1
    This can help a lot: [C Right-Left Rule](http://cseweb.ucsd.edu/~ricko/rt_lt.rule.html). Your initial "dereferencing" says vform is a pointer to a pointer to a struct that contains a pointer that contains a pointer. Your code belows say vform is a dynamically allocated array of form (I'm paraphrasing). (Actually polygon[5]). You're already in trouble. – Tibrogargan May 01 '19 at 02:12
  • there is no such field as `vpolygon` in `form`. It should be something like `(**(**vform).polygon).point->x` or `(*(*vform)->polygon)->point->x` – Serge May 01 '19 at 02:20
  • Also may be helpful http://c-faq.com/decl/spiral.anderson.html – lost_in_the_source May 01 '19 at 02:21
  • There is no need to cast the return of `malloc`, it is unnecessary. See: [Do I cast the result of malloc?](http://stackoverflow.com/q/605845/995714) – David C. Rankin May 01 '19 at 02:50

1 Answers1

1

The code below should compile in what you seem to want. There are however a lot of issues with what you're doing that may not be immediately obvious, but I'll go into that a little below.

typedef struct point {
    int x;
} point;

typedef struct polygon {
    // dynamically allocated array of point
    point *point;
} polygon;

typedef struct form {
    // dynamically allocated array of polygon
    polygon *polygon;
} form;

form *vform;
vform = malloc(sizeof(form) * 5);
vform->polygon = malloc(sizeof(polygon) * 5);
vform->polygon->point = malloc(sizeof(point) * 5);
vform->polygon->point->x = 1;

First issue is that you're mixing up your variables with the members of your structures. Your form structure has no element called "vpolygon". Just because your "vpolygon" variable is a polygon structure doesn't mean you can suddenly refer to the polygon member of a form variable by calling it "vpolygon".

Secondly, you're casting the return value of malloc. Don't do this. See do I cast the result of malloc

Thirdly, your form malloc is allocationing enough memory for 5 form structures, but casting the result to a pointer to a pointer to form. The malloc should possibly be malloc(sizeof(form *) * 5) but I'm guessing you really meant (vform *)malloc... not (vform **)malloc....

Fourth, you're dynamically allocating arrays and pointing your variables at the first element in the array but you don't seem to have any mechanism to detect the size of the array. You need a method to track the size of the array so you don't accidentally cause a segmentation fault by going off the end of the array. (Three common methods: 1) track the number of elements allocated. 2) Mark the end of the array with some marker value and check for if, 3) hard-code it. All have trade-offs)

Fifth. You want to store the original value returned by malloc so you can free it at some point - if you modify what vfrom points to you'll lose that original address and cause memory leaks.

Tibrogargan
  • 4,508
  • 3
  • 19
  • 38
  • Wow, this cleared my mind. One last thing, what is the correct way to change the positions "inside the polygon"? vform->(polygon+1)->point->x = 1; didn't work – Prot May 01 '19 at 03:12
  • @Prot to change which point `vform->polygon` refers to you can do `vform->polygon++` or `++vform->polygon` - or frankly any sort of [pointer arithmetic](/questions/394767/pointer-arithmetic). I think what you're after is `(vform->polygon + 1)->point->x = 1`; But I need to caution you that without any form of bounds checking that's got a high risk – Tibrogargan May 01 '19 at 03:24