简体   繁体   中英

Passing data structure through glib queue

I have another pointer question, so I'd be really glad if you could help me to solve that

I have this structure:

uint8_t *reconstructed[3];

reconstructed[0] = buff_offset + (uint8_t *) malloc (buff_size);
reconstructed[1] = buff_offset + (uint8_t *) malloc (buff_size);
reconstructed[2] = buff_offset + (uint8_t *) malloc (buff_size);

I use this variable this way:

y4m_write_frame (fd_out, &ostreaminfo, &oframeinfo, reconstructed);

My task is to paralelize this app, for several reasons I need to put this structure in a GLib queue and work with that after some action.

So I put it in the queue:

g_queue_push_tail(queue, (gpointer) reconstructed);

But now I don't know how to get it from there. I tried:

uint8_t * const * frame = (uint8_t * const *) g_queue_pop_head(queue);
y4m_write_frame (fd_out, &ostreaminfo, &oframeinfo, frame);

But application fails with Segmentation fault.

Can any one help me please? I don't get the whole pointers problem.

You are pushing memory that is allocated on the stack onto the end of your queue:

uint8_t *reconstructed[3];

And then trying to pull that out of the queue way off somewhere else. By the time you pull things out of the queue, the space on the stack for your three element reconstructed array is almost certainly being used for something else. I think you'll have to change reconstructed to a uint8_t ** and allocate it on the heap:

unint8_t **reconstructed;
reconstructed = malloc(3 * sizeof(uint8_t *));
/* Proceed as before. */

This will keep the reconstructed memory valid (barring other bugs of course) outside the function that declares it. You'll also have to free your reconstructed value (and its elements) when you've pulled it out of the queue and are done with it; when freeing, be sure to take into account the odd offsets on the reconstructed elements.

Ok so I've also figured it out I created the wrapper I needed for another reason anyway

// structure
struct wrapper {
    uint8_t *reconstructed[3];
    int should_reconstruct;
    int run_count;
};

// malloc wrapper
struct wrapper* link = (struct wrapper*) malloc(sizeof(struct wrapper));
link->reconstructed[0] = buff_offset + (uint8_t *) malloc (buff_size);
link->reconstructed[1] = buff_offset + (uint8_t *) malloc (buff_size);
link->reconstructed[2] = buff_offset + (uint8_t *) malloc (buff_size);

// add additional informations to wrapper
link->should_reconstruct = 0;
link->run_count = run_count;
g_queue_push_tail(queue, (gpointer) link);

and when I needed to use it in a different namespace I just

struct wrapper* frame = (struct wrapper*) g_queue_pop_head(queue);
y4m_write_frame (fd_out, &ostreaminfo, &oframeinfo, frame->reconstructed);
// rest of the code

Thank you so much for your views and replies

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