【问题标题】:C: switch two struct in one array [duplicate]C:在一个数组中切换两个结构[重复]
【发布时间】:2015-08-05 22:00:28
【问题描述】:

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

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 *) 元素的通用循环缓冲区。这个数据结构工作正常。问题是这样的: 当我有一个指向该结构的指针时,为什么我不能更改该结构中的整数?

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

【问题讨论】:

  • 你能显示struct CircularBuffer 和用来操作它的函数吗?
  • 不试图重现这个,因为它甚至不会编译......没有CircularBuffer,没有temp......
  • 肯定需要一小段代码来复现,实际上给出完整的代码。也许尝试一个更小的例子来测试你在这里做的你不完全自信的事情?
  • 我尽量解释清楚,放了很多代码
  • 您的失败方式与 Olaf 在您刚刚链接的问题中指出的相同,请查看 minimal, complete and verifiable questions 上的文档。

标签: c arrays pointers struct circular-buffer


【解决方案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 分配的内存中的某处。

在 main 函数中,您进行以下调用:

    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 的相同指针, 您可以自己复制指针(而不是它们指向的数据) 进入循环缓冲区。但这很有可能导致 你还有很多问题。如果你不这样做,你可能会过得更好 期望更改数据结构的一份副本会自动 更改您之前制作的其他副本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 2019-05-12
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多