Search code examples
carrayspointersstructcircular-buffer

C: switch two struct in one array


I have to switch two elements (structures) in a data structure composed by an array. When I create a new element for the data structure, I maintain a pointer to that element, so I can modify it later. When I try to change the value, it seems to be the same as before. Can you tell me where I'm wrong?

struct TimeData {
    struct timeval time_send;
    struct timeval time_recv;
    struct timeval timeout;
    struct timeval time_stamp;
    int seq;
};

struct TimerWheel {
    struct CircularBuffer *cb;
};

struct TimeData *newTimeData(int seq, time_t sec, suseconds_t usec) {
    struct TimeData *td;

    td = malloc(sizeof(struct TimeData));

    td->seq = seq;
    td->timeout.tv_sec = sec;
    td->timeout.tv_usec = usec;

    gettimeofday(&td->time_send, NULL);

    return td;
}

int timerWheelAdd(struct TimerWheel *tw, struct TimeData *td) {
    if (circularBufferIsFull(tw->cb) == 1)
        return 1;
    else {
        circularBufferAdd(tw->cb, td);
        circularBufferShiftE(tw->cb);
        return 0;
    }
}

struct TimeData *timerWheelGetTmr(struct TimerWheel *tw) {
    if (circularBufferIsEmpty(tw->cb) == 1)
        return NULL;
    else {
        struct TimeData *td;
        td = circularBufferRead(tw->cb);
        circularBufferShiftS(tw->cb);
        return td;
    }
}

int main() {
    struct TimeData *td5;
    struct TimeData *td6;

    td5 = newTimeData(1, 3, 5000);
    td6 = newTimeData(2, 5, 6000);

    struct TimerWheel *tw1 = newTimerWheel(10);

    timerWheelAdd(tw1, td5);
    timerWheelAdd(tw1, td6);

    ///////NOW I TRY TO MODIFY td5
    td5->seq = 67;

    struct TimeData *temp;
    while ((temp = timerWheelGetTmr(tw1)) != NULL)
        printf("%d\n", temp->seq);
    //////td5->seq is the same as before
}

EDIT

The CircularBuffer struct is only a generic circular buffer of (void *) element. This data structure works fine. The problem is this: why I cannot change an integer in a struct when I have a pointer to that struct?

This is my CircularBuffwer: C : Insert/get element in/from void array


Solution

  • In the question you linked to, you have this implementation of circularBufferAdd:

    void circularBufferAdd(struct CircularBuffer *cb, void* obj) {
        memcpy(cb->buffer + cb->E, obj, cb->sizeOfType);
    }
    

    Now as you are aware there are problems with this function; that's why you posted the other question. But here's the answer you accepted:

        memcpy((char *)cb->buffer + (cb->E * cb->sizeOfType), obj, cb->sizeOfType);
    

    The common theme here is that you are copying the contents of the struct that obj points to (not the pointer obj itself) somewhere into the memory allocated for cb->buffer.

    From the main function, you make this call:

        timerWheelAdd(tw1, td5);
    

    So now you have copies of the same data in two places: one place that td5 points to, and one place within the memory block that cb->buffer points to. (Notice that the temporary variable obj within that function call also pointed to the same memory as td5, but that pointer went out of scope at the end of the function.)

    So now when you set td5->seq = 67; it modifies the seq field in the copy of the struct that td5 points to. But td5 doesn't point anywhere inside the memory block that cb->buffer points to, so of course the modification of td5->seq doesn't modify anything in cb->buffer, and when you print out the contents of cb->buffer you see what you put in there when you called timerWheelAdd(tw1, td5); and you do not see the change you made to td5 after it was copied.

    If you want to still be able to modify the "contents" of the circular buffer using the same pointers you passed to circularBufferAdd, you could copy the pointers themselves (not the data they point to) into the circular buffer. But that has the very good chance to cause a lot more problems for you. You may be better off if you just don't expect that changing one copy of a data structure will automatically change other copies you made earlier.