0

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

Community
  • 1
  • 1
Simon
  • 95
  • 1
  • 11
  • Can you show `struct CircularBuffer` and the functions used to manipulate it? – Filipe Gonçalves Aug 05 '15 at 22:07
  • Not trying to reproduce this because it won't even compile ... no `CircularBuffer`, no `temp` ... –  Aug 05 '15 at 22:07
  • Definitely need a smaller piece of code to reproduce, and actually give complete code. Maybe try a smaller example to test something you're doing here that you're not completely confident about? – Veltas Aug 05 '15 at 22:16
  • I tried to be as explanatory as possible , putting a lot of code – Simon Aug 05 '15 at 22:23
  • 1
    You're failing in the same way that Olaf identified in the question you just linked, check the docs on [minimal, complete and verifiable questions](http://stackoverflow.com/help/mcve). – Veltas Aug 05 '15 at 22:39
  • Sorry, i am a noob :( Now i try to edit the main post with a smaller and complete example. – Simon Aug 05 '15 at 22:44
  • Your `circularBufferAdd` does not change `E` as it should. That means you are always overwriting the first element. If you have already fixed that then don't just link to old (incorrect) code. Provide the most up to date code and put it all in this question (not as a link). – kaylum Aug 05 '15 at 22:50
  • This is essentially the same problem as in the previous question, and the solution is pretty much the same as in the previous question, so I've closed this as a duplicate of the previous question. – Jonathan Leffler Aug 06 '15 at 04:39

1 Answers1

1

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.

David K
  • 3,147
  • 2
  • 13
  • 19