简体   繁体   中英

Set pointer to array of structs equal to array of structs

I have a struct foo_t that, within it, has a pointer to an array of struct, bar_t . I also have a struct spam_t that, with in, has an array of struct bar_t . My goal is to set the pointer to the array of bar_t in foo_t to the array of bar_t in spam_t .

The following program attempts to do this. My expectation then, is that if I change, for example, spam->bar[2].var2 , I should see the new value reflected in foo.bar[2]->var2 . However, I don't see this happening. The only instance where changes to spam->bar appear in foo.bar is if I change element [0] . What's going on here? How can I properly point foo.bar to the same array as spam->bar ?

#include <stdlib.h>
#include <string.h>

typedef struct {
    uint16_t var1;
    uint16_t var2;
} bar_t ;

typedef struct {
    bar_t    (* bar)[3];
    uint8_t  spare;
} foo_t;

typedef struct {
    bar_t    bar[3];
} spam_t;


void printVar(foo_t foo, spam_t * spam)
{
    printf("foo.bar[0]->var1:  %d\n",   foo.bar[0]->var1);
    printf("foo.bar[1]->var1:  %d\n",   foo.bar[1]->var1);
    printf("foo.bar[2]->var1:  %d\n",   foo.bar[2]->var1);

    printf("spam->bar[0].var1: %d\n",   spam->bar[0].var1);
    printf("spam->bar[1].var1: %d\n",   spam->bar[1].var1);
    printf("spam->bar[2].var1: %d\n\n", spam->bar[2].var1);

    printf("foo.bar[0]->var2:  %d\n",   foo.bar[0]->var2);
    printf("foo.bar[1]->var2:  %d\n",   foo.bar[1]->var2);
    printf("foo.bar[2]->var2:  %d\n",   foo.bar[2]->var2);

    printf("spam->bar[0].var2: %d\n",   spam->bar[0].var2);
    printf("spam->bar[1].var2: %d\n",   spam->bar[1].var2);
    printf("spam->bar[2].var2: %d\n\n", spam->bar[2].var2);
}

int main(int argc, char * argv[])
{
    printf("Start...\n");

    foo_t    foo;
    spam_t * spam = (spam_t *)malloc(sizeof(spam_t));

    memset(&foo, 0, sizeof(foo_t));
    memset(spam, 0, sizeof(spam_t));

    foo.bar = &(spam->bar);

    printVar(foo, spam);

    spam->bar[0].var1 = 1;
    spam->bar[1].var1 = 1;
    spam->bar[2].var1 = 0;

    spam->bar[0].var2 = 2;
    spam->bar[1].var2 = 1;
    spam->bar[2].var2 = 0;

    //foo.bar[2]->var2 = 3;

    printVar(foo, spam);

    free(spam);

    printf("Done...\n");

    return 0;
}

You correctly assign the address of the array to the pointer, but I think the way you access your elements is incorrect.

You should change

foo.bar[0]->var1

to

(*foo.bar)[0].var1

foo.bar[0]->var1 is equivalent to (*foo.bar[0]).var1 . But since foo.bar is a pointer to an array you want to first dereference the pointer and then apply the array subscription. Therefore you should write (*foo.bar)[0].var1 .

The problem is that foo.bar is a pointer to an bar_t array of size 3. So when you use foo.bar[1] you will be beyond that array.

One possible way to get around this is to use an array of size 1:

typedef struct {
    bar_t    (* bar)[1];
    uint8_t  spare;
} foo_t;

This will trigger a warning for incompatible pointer type, which it should. But it does work the way you want.

But of course, you would want to rewrite it in a more proper way, but this at least demonstrate that the problem is the step size in the array.

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