Thread: Valgrind error help

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    18

    Valgrind error help

    Hello all, I have a simple program that takes in user inputs into a queue and spits them back out if EOF is encountered. My problem lies in the errors I'm having when running valgrind. I'm afraid I can't figure out where the error originates and decided it would be better if I were to ask my peers here instead. Here is the code:

    Code:
    #include <assert.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "auxlib.h"
    #include "queue.h"
    
    void putinqueue (queue_ref queue, FILE *input, char *filename) 
    {
       char buffer[1024];
       int linenr;
       
       for (linenr = 1; ; ++linenr) 
       {
          char *linepos = fgets (buffer, sizeof buffer, input);
          if (linepos == NULL) 
             break;
             
          linepos = strchr (buffer, '\n');
          
          if (linepos == NULL) 
             eprintf ("%: %s[%d]: unterminated line\n", filename, linenr);
          else 
             *linepos = '\0';
             
          linepos = strdup (buffer);
          assert (linepos != NULL);
          insert_queue (queue, linepos);
       }
    }
    
    void putfileinqueue (queue_ref queue, char *filename) 
    {
       FILE *input = fopen (filename, "r");
       
       if (input == NULL) 
          syseprintf (filename);
       else 
       {
          putinqueue (queue, input, filename);
          
          if (fclose (input)) 
             syseprintf (filename);
       }
    }
    
    int main (int argc, char **argv) 
    {
       queue_ref queue = new_queue();      //declare queue_ref ADT
       set_execname (argv[0]);
       
    
       if (argc < 2)
          putinqueue (queue, stdin, "-");
       else 
       {
          int argi;
          
          for (argi = 1; argi < argc; ++argi) 
          {
             if (strcmp (argv[argi], "-") == 0)
                putinqueue (queue, stdin, "-");
             else 
                putfileinqueue (queue, argv[argi]);     
          }
       }
    
       while (! isempty_queue (queue)) 
          printf ("%s\n", remove_queue (queue));
    
       free_queue (queue);
       
       return get_exitstatus();
    }

    I should probably mention here that queue_ref below is a pointer and queue_item_t is a string.

    Code:
    #include <assert.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "queue.h"
    
    static char *queue_tag = "struct queue";
    static char *queuenode_tag = "struct queuenode";
    
    typedef struct queuenode *queuenode_ref;
    struct queuenode 
    {
       char *tag;
       queue_item_t item;
       queuenode_ref link;
    };
    
    struct queue 
    {
       char *tag;
       queuenode_ref top;
       queuenode_ref front;
       queuenode_ref rear;
    };
    
    //returns pointer to queue_ref
    queue_ref new_queue (void) 
    {
       //STUBPRINTF ("return NULL\n");
       queue_ref queue_ptr = NULL;
       queue_ptr = malloc ( sizeof ( struct queue));
       
       return queue_ptr;
    }
    
    void free_queue (queue_ref queue) 
    {
       assert (is_queue (queue));
       assert (isempty_queue (queue));
       //memset (queue, 0, sizeof (struct queue));
       for (queuenode_ref curr = queue->top; curr != NULL; ) 
       {
          queuenode_ref temp = curr->link;
          free (curr->item);
          free (curr);
          curr = temp;
       }
       free (queue);
    }
    
    void insert_queue (queue_ref queue, queue_item_t item) 
    {
       queue_item_t word = item;
       queue->tag = queue_tag;
       
       queuenode_ref temp = NULL;
       temp = malloc (sizeof (struct queuenode));
       assert (temp != NULL );
       temp->tag = queue_tag;
       temp->item = word;
       temp->link = NULL;
         
       if ( queue->rear == NULL )
       {
          queue->front = temp;
          queue->top = temp;
       }
       else
          queue->rear->link = temp;
            
       queue->rear = temp;
       //STUBPRINTF ("item =\n\t\"%s\"\n", item);
       assert (is_queue (queue));
    }
    
    queue_item_t remove_queue (queue_ref queue) 
    {
       assert (is_queue (queue));
       assert (! isempty_queue (queue));
       
       queue_item_t item = queue->front->item;
       
       queue->front = queue->front->link;
       return item;
          
    }
    
    bool isempty_queue (queue_ref queue) 
    {
       if ( !(is_queue (queue)) )
       {
          free ( queue);
          assert (is_queue (queue));
       }
       return queue->front == NULL;
    }
    
    bool is_queue (queue_ref queue) 
    {
       return queue != NULL; //&& queue->tag == queue_tag;
    }
    I've left out auxlib.c which is just to parse errors in input/output. Also left out are the header files (.h). I'm confident that these snippets of my program will suffice. This is the error I'm getting from valgrind:

    Code:
    [test@unix3 queueDir]$ valgrind --leak-check=full --track-origins=yes \
    ? catqueue
    ==22212== Memcheck, a memory error detector
    ==22212== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
    ==22212== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
    ==22212== Command: catqueue
    ==22212== 
    This
    ==22212== Conditional jump or move depends on uninitialised value(s)
    ==22212==    at 0x400DA3: insert_queue (queue.c:66)
    ==22212==    by 0x400AE3: putinqueue (main.c:31)
    ==22212==    by 0x400B8A: main (main.c:57)
    ==22212==  Uninitialised value was created by a heap allocation
    ==22212==    at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
    ==22212==    by 0x400C69: new_queue (queue.c:34)
    ==22212==    by 0x400B5F: main (main.c:52)
    ==22212== 
    is
    a
    test
    This
    is
    a
    test
    ==22212== 
    ==22212== HEAP SUMMARY:
    ==22212==     in use at exit: 0 bytes in 0 blocks
    ==22212==   total heap usage: 9 allocs, 9 frees, 143 bytes allocated
    ==22212== 
    ==22212== All heap blocks were freed -- no leaks are possible
    ==22212== 
    ==22212== For counts of detected and suppressed errors, rerun with: -v
    ==22212== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
    Last edited by edishuman; 11-12-2011 at 03:34 PM.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Because you create a new queue and do not initialize "rear", but count on reading a value from there.

    Technically, on a modern OS malloc'd memory is zero'd out automatically, so your code works (NULL==0), but counting on that is a bad practice by the C standard. When you allocate a new struct, explicitly initialize all the members before you read from them.
    Last edited by MK27; 11-12-2011 at 03:39 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory Allocation Error - /w Valgrind Output
    By Ggregagnew in forum C Programming
    Replies: 5
    Last Post: 12-02-2010, 04:02 PM
  2. Valgrind
    By anirban in forum C Programming
    Replies: 2
    Last Post: 10-26-2010, 10:07 PM
  3. How Far Should You Go To Use Valgrind?
    By jeffcobb in forum C++ Programming
    Replies: 36
    Last Post: 02-25-2010, 05:02 PM
  4. valgrind error - still reachable
    By myle in forum C Programming
    Replies: 1
    Last Post: 04-19-2009, 08:57 PM
  5. Is valgrind always right?
    By g4j31a5 in forum Linux Programming
    Replies: 3
    Last Post: 07-16-2007, 10:39 PM