سؤال

I have a generic linked list that looks like this:

queue.hpp

typedef struct queue_node
{
    struct queue_node *next;
    struct queue_node *prev;
    void *data;
    int32_t index;
} queue_node;

typedef struct queue 
{
    struct queue_node *head;
    struct queue_node *tail;
    struct queue_node *current;
    int32_t max_entries;
    int32_t num_entries;
} queue;

I thought this would be simple, but I'm having a really hard time making use of the void *data to handle arbitrary arguments (usually custom objects defined elsewhere). When I exxtract the data from the node, I tried casting it as the desired object. In this case, I tried to cast as proc_instruction to read back the data that I stored there -> segmentation fault:

procsim.cpp:

while (total_instructions < 5000 && fscanf(proc_tf, "%x %d %d %d %d\n", 
                          &p_inst->address,
                          &p_inst->type, 
                          &p_inst->dst, 
                          &p_inst->src[0], 
                          &p_inst->src[1]) != EOF) {
      trace_queue = append_node(trace_queue,p_inst); // stores p_inst in new trace_queue node
      trace_queue->current = goto_queue_first(trace_queue); 
      p_inst = (proc_instruction*)trace_queue->current->data; // trying to get stored inst from trace_queue node
      printf("%x %d %d %d %d\n",p_inst->address,p_inst->type, p_inst->dst, p_inst->src[0], p_inst->src[1]);
    }

Here is where I append the data (if it helps):

queue.cpp

queue *append_node(queue *app_q, void *app_data)
{
    if(!queue_is_empty(app_q))
      app_q->current = goto_queue_last(app_q);

    queue_node *n = (queue_node *)emalloc(sizeof(*n));
    n->prev = app_q->current;
    n->next = app_q->tail;
    app_q->current = goto_queue_last(app_q);
    app_q->current->data = app_data;
    app_q->num_entries++;
    app_q->current->index = app_q->num_entries;

    return app_q;
}

I've seen example code where people have done this, but I can't seem to get it. I must be making a fundamental mistake here. Thanks guys/girls.

هل كانت مفيدة؟

المحلول 2

Ok, I did a silly thing: I was using g++ instead of gcc which matters when using casting with a "void *" - c++ requires more logic to do this than c does. Here is the code now:

procsim.c

 /* Copy the trace file into a linked list */
int total_instructions = 0;
proc_instruction *p_inst = (proc_instruction *)emalloc(sizeof(*p_inst));
queue *trace_queue = init_queue();
proc_instruction *inst;

while (total_instructions < 5000 && fscanf(proc_tf, "%x %d %d %d %d\n", 
                      &p_inst->address,
                      &p_inst->type, 
                      &p_inst->dst, 
                      &p_inst->src[0], 
                      &p_inst->src[1]) != EOF) {
  trace_queue = append_node(trace_queue,p_inst);
  inst = trace_queue->current->data;    // no need to explicitly cast using gcc
  printf("%x %d %d %d %d\n",inst->address,inst->type, inst->dst, inst->src[0], inst->src[1]);
  trace_queue->current = trace_queue->current->next;
  ++total_instructions;   
}

The output prints me exactly what I expected, the data from the proc_tf data file.

I also forgot advance the list by setting current node to the next node, so it kept printing the same thing over and over.

Thanks.

نصائح أخرى

seems queue_node *current is not necessary in "append_node" since you want to append the new node to the tail.

And I didn't see the initialization of "app_q", I assume memset(0) is called when it is allocated.

queue *append_node(queue *app_q, void *app_data)
{
    queue_node *n = (queue_node *)emalloc(sizeof(*n));

    memset(n, 0, sizeof(queue_node));
    if ( NULL == app_q->head)
    {
        app_q->head = n;
        app_q->tail = n;
    }
    else
    {
        n->prev = app_q->tail;
        n->next = NULL;

        app_q->tail->next = n;
        app_q->tail = n;
    }

    n->data = app_data;
    n->index = app_q->num_entries;

    return app_q;
 }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top