#c #queue #memcpy
#c #очередь #memcpy
Вопрос:
Я пытаюсь СКОПИРОВАТЬ очередь в другую очередь, чтобы, если я уничтожу одну, она не уничтожит другую.
Я пытался использовать memcpy
этот способ:
memcpy(queue1, queue2, sizeof(queue2));
Но я получаю следующую ошибку:
ожидается ‘void * restrict’, но аргумент имеет тип ‘Queue’
Возможно ли скопировать одну очередь в другую?
Редактировать
Это структура очереди:
typedef char *Following;
typedef struct _NodeQ {
Following element;
struct _NodeQ * next;
} NodeQ;
typedef struct {
int error;
NodeQ * first;
NodeQ * last;
} Queue;
Комментарии:
1. под «очередью» вы подразумеваете «массив»? Пожалуйста, лучше объясните, что такое ваша очередь.
2. Под очередью я подразумеваю: динамический FIFO. Я отредактировал вопрос, чтобы вы могли видеть структуру.
Ответ №1:
memcpy
это определенно не так, потому что это приведет вас только к выполнению «мелкой копии». Если вы считаете, что ваш объект может хранить указатели на внешние данные, поверхностная копия этого объекта будет указывать на те же самые внешние данные, а не дублировать все («глубокая копия»).
Метод выполнения глубокой копии полностью зависит от реализации. Похоже, что ваша очередь использует простую реализацию связанного списка (см., Как Каждая 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 memoryn");
}
// 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 memoryn");
}
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(amp;queue1, amp;queue2, sizeof(queue2));
Приведенная выше строка перезапишет структуру queue1
содержимым queue2
, эффективно копируя quque2
queue1
.