Search code examples
cpointersstructtypedef

C variables in struct have same address each other


define code :

#include <stdio.h>
#include <string.h>

typedef int count_t;

typedef struct ptid_t {
    short           index;    
    short           ioffset;   
    unsigned char           type;      
    unsigned char           networkType;
} ptid_t;

typedef union ptid_lst {
    count_t count; 
    ptid_t  item[1];
} plist_t;

main code :

int main(void) {

    plist_t test;

    memset(&test, 0x0, sizeof(plist_t));

    test.count = 0xABCDABCD;

    printf("%x\n", test.count);
    printf("%x\n", test.item[0].index);
    printf("%x\n", test.item[0].ioffset);

    return 0;
}

console output :

abcdabcd
ffffabcd
ffffabcd

I just trying to change struct first value 'count' but other variables are changed.
The change value is 'count' in plist_t. but, why index and ioffset variables are changed both?
Because of this situation, I try to get the variable's address and result :

0x80479f4
0x80479f4
0x80479f6

The 'count' variable and item[0] struct has same address. why occured this situation?
In oppsite case are same too.

int main(void) {

    plist_t test;

    memset(&test, 0x0, sizeof(plist_t));

    test.item[0].index = 0xabcd;
    test.item[0].ioffset = 0xabc0;

    printf("%x\n", test.count);
    printf("%x\n", test.item[0].index);
    printf("%x\n", test.item[0].ioffset);

    return 0;
}


console output:
abc0abcd
ffffabcd
ffffabc0

Solution

  • Because plist_t isn't a struct, it's a union

    In C, each member of a union starts at the same memory address.

    If you want to change them independently, simply convert plist_t into a struct instead:

    typedef struct ptid_lst {
        count_t count; 
        ptid_t  item[1];
    } plist_t;