简体   繁体   中英

Pass struct by reference, return pointer to new struct

I would like to pass a struct to a function by reference, create a new instance of a struct, destroy the original and return a new struct correctly. A specific example of such case is a queue resize function:

A queue structure itself:

// Queue for storage of pairs
typedef struct {
    int n;        // size of queue
    int m;        // no. of pairs in queue
    int f;        // index of front element
    int r;        // index of rear element
    pair *pairs;  // array of pairs
} queue;

Queue initialisation routine:

// Initialises queue
int init(int const *n, queue *q) {

    q->n = *n;
    q->m =  0;
    q->f =  0;
    q->r =  0;

    q->pairs = (pair*) calloc(q->n, sizeof(pair));

    return 0;
}

Queue destruction routine:

// Destroys queue
int destroy(queue *q) {

    q->n = 0;
    q->m = 0;
    q->f = 0;
    q->r = 0;
    free(q->pairs);

    return 0;
}

Enqueue routine:

// Adds pair to queue
int enqueue(pair *p, queue *q) {

    // resize queue if necessary
    if (isfull(q))  int status = resize(q);

    if (q->m > 0)  q->r = (++q->r) % q->n;
    q->pairs[q->r] = *p;
    q->m++;

    return 0;
}

My take at the queue resizing routine (currently it crashes with a floating point exception). I believe to resize a queue correctly I need to pass a pointer to a queue pointer, but so far I am unable to achieve this.

// Resizes queue
int resize(queue *q) {

    // initialise new queue
    const int N = 2*q->n;
    queue p;
    init(&N, &p);

    // copy pairs from old to new queue
    for (int i = 0; i < q->m; i++) {
        pair f = dequeue(q);
        enqueue(&f, &p);
    }

    // destroy old queue
    destroy(q);

    // re-assign pointer to new queue
    q = &p;

    return 0;
}

Reassigning the pointer is completely useless. You changed it locally, but that didn't modify the original object. What you did was destroying the original queue, with nothing left in place.

What you want to do is to modify provided object in-place .

For example:

*q = p; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM