【问题标题】:How can I make a copy of a queue in C?如何在 C 中制作队列的副本?
【发布时间】:2020-09-27 19:37:23
【问题描述】:

我正在尝试将一个队列复制到另一个队列中,以便在我销毁一个队列时,它不会破坏另一个队列。

我试过这样使用memcpy

memcpy(queue1, queue2, sizeof(queue2));

但我收到以下错误:

预期为“void * restrict”,但参数类型为“队列”

是否可以将一个队列复制到另一个队列中?

编辑

这是队列的结构:

typedef char *Following;

typedef struct _NodeQ {
    Following element;
    struct _NodeQ * next;
} NodeQ;


typedef struct {
    int error;
    NodeQ * first;
    NodeQ * last;
} Queue; 

【问题讨论】:

  • “队列”是指“数组”吗?请更好地解释你的队列是什么。
  • 队列我的意思是:动态 FIFO。我编辑了问题,以便您查看结构。

标签: c queue memcpy


【解决方案1】:

memcpy 绝对不是这样,因为那只会让您执行“浅拷贝”。如果您认为您的对象可以存储指向外部数据的指针,那么该对象的浅拷贝将指向完全相同的外部数据,而不是复制所有内容(“深拷贝”)。

(image source)

执行深拷贝的方法完全取决于实现。看起来您的队列正在使用简单的链表实现(请参阅每个 NodeQ 结构如何包含指向另一个 NodeQ 结构的指针,该结构具有指向另一个结构的指针,依此类推)。这在 C 中很常见。困难的部分是弄清楚如何复制队列中每个对象的“数据”部分(在本例中为 Following 类型变量)。我不知道您使用的是哪种库或框架定义了 Queue 类型,您应该参考一些文档来帮助您了解具体细节。谁知道呢,也许你会找到一种受图书馆支持的方式来复制你想要的方式。不过,我会尝试做你想做的事,但有一些假设。

从现在开始的推测

这只是一个猜测,但似乎Following 可以表示一个字符串,因为它是一个字符指针。我在下面编写的代码使用了这个假设。请注意,虽然它未经测试且有点仓促,但我只是想说明在您的场景中执行手动深拷贝的情况。

Queue queue2;
NodeQ *e2, *e2prev = NULL, *e2first = NULL;

// Iterate through all elements of the first queue
for (NodeQ *e1 = queue1.first; e1; e1 = e1->next) {

    // Allocate memory for the new element of queue 2
    if (!(e2 = (NodeQ*)malloc(sizeof(NodeQ)))) {
        printf("not enough memory\n");
    }

    // Remember the first element of queue for future use
    if (!e2first)
        e2first = e2;

    // Note that strlen here could cause a segfault if my guess that "element" is a string is wrong
    size_t buflen = strlen(e1->element) + 1; // +1 for null terminator
    if (!(e2->element = (Following)malloc(sizeof(char) * buflen))) {
        printf("not enough memory\n");
    }
    strcpy(e2->element, e1->element);

    e2->next = NULL;

    // Link new element with previous element
    if (e2prev)
        e2prev->next = e2;

    e2prev = e2;
}

queue2.error = queue1.error;
queue2.first = e2first;
queue2.last  = e2;

【讨论】:

    【解决方案2】:

    您的编译器警告您memcpy 需要两个指针作为第一个参数。这才是正确的复制方式:

    memcpy(&queue1, &queue2, sizeof(queue2));
    

    以上行将用queue2 的内容覆盖结构queue1,有效地将quque2 复制到queue1

    【讨论】:

      猜你喜欢
      • 2013-05-17
      • 2013-04-22
      • 2013-06-30
      • 2012-08-19
      • 1970-01-01
      • 1970-01-01
      • 2020-06-27
      • 2021-11-18
      • 2012-03-06
      相关资源
      最近更新 更多