user1674921
user1674921

Reputation: 11

Using unions with structures

I have a structure like this:

struct data
{ 
    char abc[10];
    int cnt;
    struct data *next, *prior;
};
struct data *start, *last;
struct data *start1, *last1;
struct data *start2, *last2;

The integer 'cnt' can have two values. The pointers:

struct data *start, *last;

are used to link all data with all values of 'cnt'. The pointers:

struct data *start1, *last1;
struct data *start2, *last2;

are used to link data when the value of 'cnt' is either 1 or 2. My problem is that when I change the value of 'abc' or 'cnt' for one linked list, say 'start->abc', the value 'start1->abc' and 'start2->abc' are unchanged because they live in different memory locations.
I would like a change in data under one list to be reflected in the other two lists. I believe 'unions' could help me do this but I don't know how to set it up.

Any help appreciated!

Upvotes: 1

Views: 232

Answers (4)

Kos
Kos

Reputation: 72241

Nope, can't be done.

If even you come up with a solution that uses unions to get this done, you'll essentially have some data objects allocated in such a way that they overlap each other in memory. You'd end up with a contiguous memory block.

Rather than that, disregard the linked list altogether and use an array:

struct data {
    char abc[10];
    int data;
}

struct data datas[50];
struct data* some = datas[20];
struct data* prev = some - 1;
struct data* next = some + 1;

(Don't go out of bounds.)


If you really want a linked list for some reason, the whole point of them is that each element can be anywhere in the memory. This means that each element needs to remember the address of the next and the previous in order to allow two-way navigation.

Therefore, rather than thinking about union tricks, just make a function insertData or removeData that do basic operations on a list and also fixes all the pointers in neighbouring elements.

Upvotes: 1

K Scott Piel
K Scott Piel

Reputation: 4380

Use a set of arrays to hold the data, and use a pointer to those arrays from your structures. Then "linked" entries can point to the same data buffer...

struct data
{ 
    char* abc;
    int cnt;
    struct data *next, *prior;
};
struct data *start, *last;
struct data *start1, *last1;
struct data *start2, *last2;

char abcBuffer[2][10];

and in some function somewhere...

start->abc = abcBuffer[start->cnt];
start1->abc = abcBuffer[start1->cnt];
start2->abc = abcBuffer[start2->cnt];

In this case, changing the content of abcBuffer[n] will reflect the same change across all of the structures linked to that buffer. The key, however, is that you cannot do this using a "shared" structure such as a union, but have to manage it in your code.

Upvotes: 0

Doug Currie
Doug Currie

Reputation: 41170

If you want the data to live on two lists simultaneously, the "all" list and the "cnt" list, then you need two sets of start, last pointers in the structure.

struct data
{ 
    char abc[10];
    int cnt;
    struct data *next_all, *prior_all;
    struct data *next_cnt, *prior_cnt;
};

When you change the value of cnt, you must remove the data from the next_cnt, prior_cnt list (corresponding to start1, last1 or start2, last2) and add it to the other.

Upvotes: 0

MOHAMED
MOHAMED

Reputation: 43518

char global_abc[10];
int global_cnt;

struct data
{ 
    char *abc;
    int *cnt;
    struct data *next, *prior;
};

start->abc = start1->abc = start2->abc = global_abc;
start->cnt = start1->cnt = start2->cnt = aglobal_cnt;

And now when you changed the

strcpy(start->abc, "any");

then it will be changed for the other elements.

And when you changed the

*(start->cnt) = 5;

then it will be changed for the other elements.

Upvotes: 0

Related Questions