C:在一个数组中切换两个结构

时间:2015-08-05 22:00:28

标签: c arrays pointers struct circular-buffer

我必须在由数组组成的数据结构中切换两个元素(结构)。当我为数据结构创建一个新元素时,我维护了一个指向该元素的指针,所以我可以稍后修改它。当我尝试更改值时,它似乎与之前相同。你能告诉我哪里错了吗?

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
}

修改

CircularBuffer结构只是(void *)元素的通用循环缓冲区。这种数据结构很好。问题是这样的: 为什么当我有一个指向该结构的指针时,我无法更改结构中的整数?

这是我的CircularBuffwer: C : Insert/get element in/from void array

1 个答案:

答案 0 :(得分:1)

在你链接的问题中,你有这个实现 circularBufferAdd

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

现在你知道这个功能有问题;那是 为什么你发布了另一个问题。但这是你接受的答案:

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

这里的共同主题是您正在复制结构的内容 obj指向(不是指针obj本身) 在为cb->buffer分配的内存中的某处。

在主要功能中,您可以拨打此电话:

    timerWheelAdd(tw1, td5);

现在您在两个地方拥有相同数据的副本: td5指向的一个地方,以及一个地方 cb->buffer指向的内存块。 (请注意该函数调用中的临时变量obj 也指向与td5相同的内存,但该指针消失了 功能结束时的范围。)

现在,当您设置td5->seq = 67;时,它会修改其中的seq字段 td5指向的结构的副本。但td5并不指向任何地方 在cb->buffer指向的内存块内, 因此,td5->seq的修改当然不会修改任何内容 在cb->buffer中,当您打印出cb->buffer的内容时 当你打电话给timerWheelAdd(tw1, td5);时,你会看到你放在那里的东西 并且你看到你在复制后对td5所做的更改。

如果你想仍然能够修改的“内容” 使用传递给circularBufferAdd的相同指针的循环缓冲区, 你可以复制指针本身(而不是他们指向的数据) 进入循环缓冲区。但这有很好的机会 给你带来更多问题。如果你不这样做,你可能会更好 期望自动更改数据结构的一个副本 更改您之前制作的其他副本。