Lasse Meyer
Lasse Meyer

Reputation: 1479

How to change value in array in struct pointer from array?

I have an array of structs of type can_frame, defined in can.h as the following:

struct can_frame {
    canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
    __u8    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
    __u8    __pad;   /* padding */
    __u8    __res0;  /* reserved / padding */
    __u8    __res1;  /* reserved / padding */
    __u8    data[CAN_MAX_DLEN] __attribute__((aligned(8)));
};

I initialize the structs like this:

struct can_frame frame2;
frame2.can_id =  0x124;
frame2.can_dlc = 8;
frame2.data[0] = 0x00;
frame2.data[1] = 0x01;

The array is created like this:

struct can_frame frames[2];
frames[0] = frame;
frames[1] = frame2;

Later, in the same function, but in a while loop, I'm trying to change one byte from the data array, from one of the frames. First, I try to get a pointer to one of the frames, to work with it further:

struct can_frame* to_change = &(frames[change_frame]);

Later, I try to update one of the values like this:

to_change->data[update_index] = anotherRandomNumber;

However, the value in the original frame doesn't change. What do I need to do differently, to change the value in the original, instead of a copy?

Upvotes: 1

Views: 393

Answers (2)

Jimbo
Jimbo

Reputation: 4515

I had to do a bit of guess work about what you wanted so not sure this will be it, but let me know...

In the lines

struct can_frame frames[2];
frames[0] = frame;
frames[1] = frame2;

I assume that frame and frame2 are two other structures defined like struct can_frame frame, frame2 and then initialised.

In the line

frames[0] = frame;

frames[0] gets a copy of the data in frame.

So When you do

struct can_frame* to_change = &(frames[change_frame]);
...    
to_change->data[update_index] = anotherRandomNumber;

And then check either frame or frame2, they have not been modified, because you have only modified the copy of their data in the frames[] array.

To change this you need to use an array of pointers to struct can_frame:

struct can_frame *frames[2];
frames[0] = &frame;
frames[1] = &frame2;
....
struct can_frame* to_change = frames[change_frame];
to_change->data[update_index] = anotherRandomNumber;

Upvotes: 1

Gerhardh
Gerhardh

Reputation: 12404

Based on your information you seem to have wrong expectations:

However, the value in the original frame doesn't change.

What you show us is this:

First you prepare a structure for a CAN frame:

struct can_frame frame2;
frame2.can_id =  0x124;
frame2.can_dlc = 8;
frame2.data[0] = 0x00;
...

Then you put this structure in an array:

struct can_frame frames[2];
frames[0] = frame;
frames[1] = frame2;

This is done by copying the content of your structure into the array. There is no link back to the memory location where your data came from.

Then you change the copied data:

struct can_frame* to_change = &(frames[change_frame]);
...
to_change->data[somewhatRandomNumber] = anotherRandomNumber;

Now you expect the original frame to change. This will not happen. After copying data from one location to another location (which is what happens in an assignment) you have 2 totally independent locations with same content. If you change one place, the other place is not affected.

If you want frame2 to change, you must modify frame2 directly. This would leave your copy within the array untouched. You might need to change both places.

You might also change your array to hold pointers to the original structures. Then you only have one location with the data.

Upvotes: 1

Related Questions