0

I am not the greatest C programmer who ever lived so this might be a silly question but is there a way for all types of a specific struct to reference the same struct instance of another struct?

An example of this would be:

    #include <stdio.h>
#include <stdlib.h>
int idxgiver;
typedef struct component component_t;
typedef struct componentA componentA_t;
typedef struct componentB componentB_t;

static struct component{
    int idx;
};

struct componentA{
    component_t component;
};

struct componentB{
    component_t component;
};


componentA_t *componentA_init(){

    componentA_t *a = malloc(sizeof(componentA_t));
    if(a->component.idx == 0){
        a->component.idx = idxgiver;
        idxgiver++;
    }
    return a;
}



componentB_t *componentB_init(){

    componentB_t *b = malloc(sizeof(componentB_t));
    if(b->component.idx == 0){
        b->component.idx = idxgiver;
        idxgiver++;
    }
    return b;
}

int main(){

    componentA_t *a = componentA_init();
    componentB_t *b = componentB_init();

    printf("%d\n", a->component.idx);
    printf("%d\n", b->component.idx);

    componentB_t *b2 = componentB_init();
    printf("%d\n", b2->component.idx);

    return 0;
}

The goal of this code is to give each component its own distinctive value based upon its type, so ideally the results of this piece of code would be that component A gets the value 0 (which it does). Component B gets the value 1 (which it does) and component B2 also gets the value 1 (it does not it gets 2)?

So if there are any pointers to this or any ideas it would be most welcome.

  • Doesn't your compiler complain about `static struct component{ int idx; };`? – melpomene Nov 03 '18 at 20:25
  • Your code has undefined behavior. `if(a->component.idx == 0){` accesses `a->component.idx`, which is uninitialized. – melpomene Nov 03 '18 at 20:26
  • See this question [and my answer] as it may help a bit: https://stackoverflow.com/questions/52788369/assign-a-pointer-to-a-struct-that-is-a-member-of-a-struct-of-the-same-type-to-an/52788499#52788499 – Craig Estey Nov 03 '18 at 20:57

2 Answers2

0

The memory returned by malloc is uninitialized. So when you allocate space for a struct using malloc:

componentA_t *a = malloc(sizeof(componentA_t));

Then examine a field of the that struct:

if(a->component.idx == 0){

You're reading an uninitialized value. So it could be 0 or any other value.

There's no need for this check, so just remove it:

componentA_t *componentA_init(){
    componentA_t *a = malloc(sizeof(componentA_t));
    a->component.idx = idxgiver;
    idxgiver++;
    return a;
}

componentB_t *componentB_init(){
    componentB_t *b = malloc(sizeof(componentB_t));
    b->component.idx = idxgiver;
    idxgiver++;
    return b;
}

Note also that idxgiver is not explicitly initialized, but since it is defined at file scope it is implicitly initialized to 0.

dbush
  • 205,898
  • 23
  • 218
  • 273
-1

The int idxgiver is in global scope. The code works as it should. If you want componentA_t and componentB_t to have different idxgivers, then make that so, by defining two idxgivers.