-1

Having this code:

#include <stdio.h>
#include <stdlib.h>

struct Test { char c; } foo;

int main (void) {

   struct Test *ar[10];
   struct Test *(*p)[10] = &ar; // var 'p' is kind of type "struct Test ***p"

   *(*p+1) = malloc(sizeof(struct Test)*2); //alocated space in array p[0][1] for 2 structs

   //Now I would like to have 'foo' from above in p[0][1][1]

   // I cannot do "p[0][1][1] = foo", that is shallow copy
   // which means "p[0][1][1].c = 'c'" will have no effect
   // I need actually assign address to "&foo" to that pointer 'p'
   // something like "(*(*p+1)+1) = &foo", but that is error:
   //err: lvalue required as left operand of assignment

   // reason:
   p[0][1][1].c = 'c';
   printf("%c\n", foo.c) // no output because foo is not in the array (its address was not assign to the pointer 'p')

   return 0;
}

I would like to assign pointer struct Test ***p value of foo. So that I can manipulate with that pointer (declaring values in member of that struct). How to achieve this?

15
  • 4
    // var 'p' is kind of type "struct Test ***p" That's not true. [] and * are not freely interchangeable in all cases. Commented May 9, 2020 at 19:55
  • 1
    Considering that the structure is not "deep", it only have "shallow" data, what's bad with a shallow copy? Commented May 9, 2020 at 19:56
  • 1
    The type of your p is struct Test *(*)[10]. This is not the same as struct Test ***, nor are the two types compatible. If you actually want a triple pointer (and, generally speaking, you shouldn't) then that's what you should declare. Commented May 9, 2020 at 20:05
  • 1
    Moreover, neither foo itself nor its address, &foo, has type compatible with either of the other two types mentioned. It's not clear what you hope to accomplish with all this, but you would be well advised to avoid playing games. Commented May 9, 2020 at 20:07
  • 2
    Well, @Herdsman, interchanging those, by cast, for example, leads to strict aliasing violations when you access the pointed-to objects. The resulting behavior is undefined, and this sort of thing tends to get you into trouble with your compiler. As a practical matter, pointer arithmetic (and thus, the indexing operator, too) has different implications for pointers of those different types. Commented May 9, 2020 at 20:14

1 Answer 1

1

After you call malloc, ar[1] (and by extension p[0][1]) points to an array of 2 instances of struct Test. So ar[1][0] and ar[1][1] are both struct instances.

It seems like what you want is for them to be pointers so they can point to foo. So you need an extra level of indirection:

struct Test **ar[10];
struct Test **(*p)[10] = &ar;

// allocate space at p[0][1] for 2 struct pointers
*(*p+1) = malloc(sizeof(struct Test *)*2); 

p[0][1][1] = &foo;
p[0][1][1]->c = 'c';
printf("%c\n", foo.c);
Sign up to request clarification or add additional context in comments.

2 Comments

But I though, I do not have to add indirection. Well *(*ar+1) is an array (or pointer), and I thought, I could assign it an address. But you are right, I need another indirection
@Herdsman It is a pointer, but you assign the address of an array of struct instances there. If you only want one instance you can assign &foo to that directly without allocating anything.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.