-1

I'm trying to COPY a queue into another queue in order that if I destroy one, it doesn't destroy the other one.

I tried using memcpy this way:

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

But I get the following error:

expected ‘void * restrict’ but argument is of type 'Queue'

Is it possible to copy one queue into another?

EDIT

This is the structure of the queue:

typedef char *Following;

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


typedef struct {
    int error;
    NodeQ * first;
    NodeQ * last;
} Queue; 
user157629
  • 624
  • 4
  • 17

2 Answers2

3

memcpy is definitely not the way, because that would only get you as far as performing a "shallow copy". If you consider that your object can store pointers to external data, a shallow copy of that object will point to the exact same external data instead of duplicating everything ("deep copy").

shallow-vs-deep-copy-img (image source)

The method to perform a deep copy is entirely dependant on the implementation. It seems like your queue is using a simple linked list implementation (see how each NodeQ struct contains a pointer to another NodeQ struct, which has a pointer to another one, and so on). That is very common in C. The difficult part is figuring out how to copy the "data" portion of each object inside the queue (in this case the Following type variable). I can't tell what kind of library or framework you are using which defines the Queue type, you should refer to some documentation to help you on the specifics. Who knows, maybe you'll find a supported by the library way of copying the way you want. Nevertheless, I will attempt to do what you want, with some assumptions.

Speculation from this point onward

This is only a guess, but it seems like Following could represent a string, since it is a char pointer. The code I've written below uses this assumption. Note though that it is untested and a bit rushed, I'm just trying to illustrate how performing a manual deep copy may looks like in your scenario.

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;
Randoragon
  • 98
  • 1
  • 5
0

Your compiler is warning you that memcpy wants two pointers as first argument. This would be the correct way to copy:

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

The above line will overwrite the structure queue1 with the contents of queue2, effectively copying quque2 over queue1.

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128