user3211102
user3211102

Reputation: 15

C structs sharing common pointer?

I'm currently having an issue with the following struct:

typedef struct  __attribute__((__packed__)) rungInput{

operation inputOperation;   
inputType type;             
char* name;             
char numeroInput;           
u8 is_not;                  

} rungInput;

I create multiple structs like above inside a for loop, and then fill in their fields according to my program logic:

while (a < 5){
rungInput input;


(...)

Then when I'm done filling the struct's fields appropriately, I then attempt to copy the completed struct to an array as such:

rungArray[a] = input; //memcpy here instead?

And then I iterate again through my loop. I'm having a problem where my structs seem to all have their name value be the same, despite clearly having gone through different segments of code and assigning different values to that field for every loop iteration.

For example, if I have three structs with the following names: "SW1" "SW2" SW3", after I am done adding them to my array I seem to have all three structs point me to the value "SW3" instead. Does this mean I should call malloc() to allocate manually each pointer inside each struct to ensure that I do not have multiple structs that point to the same value or am I doing something else wrong?

Upvotes: 0

Views: 133

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 754620

When you write rungArray[i] = input;, you are copying the pointer that is in the input structure into the rungArray[i] structure. If you subsequently overwrite the data that the input structure is pointing at, then you also overwrite the data that the rungArray[i] structure is pointing at. Using memcpy() instead of assignment won't change this at all.

There are a variety of ways around this. The simplest is to change the structure so that you allocate a big enough array in the structure to hold the name:

enum { MAX_NAME_SIZE = 32 };

…
char  name[MAX_NAME_SIZE];
…

However, if the extreme size of a name is large but the average size is small, then this may waste too much space. In that case, you continue using a char *, but you do indeed have to modify the copying process to duplicate the string with dynamically allocated memory:

rungArray[i] = input;
rungArray[i].name = strdup(input.name);

Remember to free the memory when you discard the rungArray. Yes, this code copies the pointer and then overwrites it, but it is more resilient to change because all the fields are copied, even if you add some extra (non-pointer) fields, and then the pointer fields are handled specially. If you write the assignments to each member in turn, you have to remember to track all the places where you do this (that would be a single assignment function, wouldn't it?) and add the new assignments there. With the code shown, that mostly happens automatically.

Upvotes: 3

Nick Wilkerson
Nick Wilkerson

Reputation: 385

You should malloc memory for your struct and then store the pointers to the structs inside your array. You could also turn your structs into a linked list by adding a pointer to each struct that points to the next instance of your struct.

http://www.cprogramming.com/tutorial/c/lesson15.html

Upvotes: 0

Related Questions