CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10

Thread: qsort help

  1. #1
    Join Date
    Dec 2007
    Posts
    10

    qsort help

    I keep trying different ways of writing a compare function but when I run the program I keep getting a seg fault at the qsort function call.

    I have:
    Code:
    typedef struct
    {
        int count;
        char *data;
    }Wordrec;
    
    int comp(const void *a, const void *b)
    {
        const Wordrec **l = (const Wordrec **) a;
        const Wordrec **r = (const Wordrec **) b;
        
        return strcmp((*l) -> data, (*r) -> data);
    }
    And the qsort call:
    Code:
    qsort(record, numwords, sizeof(Wordrec), comp);
    record is a pointer to a pointer (**record), used like a dynamic array and numwords is the number of words/records.

    This is homework. I'm supposed to read in a text file, read out a text file with all the lines a certain size or less, and read out a sorted text file that has one occurrence of each word (without worrying about punctuation) and the number of times that word occurred.

    Everything but the sorted part is done, I just can't seem to get the qsort function to work right.

    Any help will be greatly appreciated. Thank you.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: qsort help

    Quote Originally Posted by Neon612 View Post
    I keep trying different ways of writing a compare function but when I run the program I keep getting a seg fault at the qsort function call.
    If this is a C++ program, you're better off using std::sort as there is no need for all of those casts, i.e. it's typesafe, and the comparison function is much simpler.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: qsort help

    Code:
    #include <algorithm>
    #include <cstring>
    struct WordRec
    {
        int count;
        char *data;
    };
    
    bool CompareWords(const WordRec& first, const WordRec& second)
    {
        return strcmp( first.data, second.data ) < 0; // return true if first comes before second, false otherwise
    }
    //...
    int main()
    {
       WordRec wr[20];  // 20 wordrecs
       //...
       std::sort( wr,  wr + 20, CompareWords );  // sorts the words in ascending order
    }
    This is an example of using std::sort.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Dec 2007
    Posts
    10

    Re: qsort help

    This is a C program, but if I need sorting for C++ I'll keep that in mind.

  5. #5
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: qsort help

    Quote Originally Posted by Neon612 View Post
    And the qsort call:
    Code:
    qsort(record, numwords, sizeof(Wordrec), comp);
    record is a pointer to a pointer (**record), used like a dynamic array and numwords is the number of words/records.
    If record points to the first item of an array of pointer to Wordrec, then the elements of the array are pointers. Hence, you are passing the wrong element size to the qsort function.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  6. #6
    Join Date
    Dec 2007
    Posts
    10

    Re: qsort help

    Thank you. Simple fix: size of(Wordrec *)

    Also on a side note: what exactly does "warning: implicit declaration of function ‘strdup’ " mean?

    From what I've been able to find that warning says something along the lines of not having the right header file imported.

    Here is the section of code I'm talking about:
    Code:
    while(fscanf(datafile, "&#37;s", newword) != EOF)
    	{
    		record = realloc(record, (numwords + 1) * sizeof(Wordrec));
    		
    		record[numwords] = (Wordrec *)malloc(sizeof(Wordrec));
    		
    		record[numwords] -> data = (char *)strdup(newword);
    		record[numwords] -> count = 1;
    		
    		for(i = 0; i < numwords; i++)
    		{
    			if(strcmp(newword, record[i]->data) == 0)
    			{
    				record[i]->count++;
    				free(record[numwords]);
    				numwords--;
    				break;
    			}
    		}
    		
    		numwords++;
    	}

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: qsort help

    Quote Originally Posted by Neon612 View Post
    Also on a side note: what exactly does "warning: implicit declaration of function ‘strdup’ " mean?

    From what I've been able to find that warning says something along the lines of not having the right header file imported.
    strdup is defined in <string.h>. However, it may be deprecated on some systems. If it's not available, it's equivalent to malloc a big enough block and then strcpy.

  8. #8
    Join Date
    Dec 2007
    Posts
    10

    Re: qsort help

    Thanks, so I need to use strcpy instead? I tried it replacing:
    Code:
    record[numwords] -> data = (char *)strdup(newword);
    with

    Code:
    strcpy(record[numwords] -> data, newword);
    but now that strcpy line is seg faulting on me.

    Do I need to do another malloc for the record[num] -> data string? Shouldn't the first malloc set aside enough space for the whole structure (count and data combined)?

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: qsort help

    Quote Originally Posted by Neon612 View Post
    Thank you. Simple fix: size of(Wordrec *)

    Also on a side note: what exactly does "warning: implicit declaration of function ‘strdup’ " mean?

    From what I've been able to find that warning says something along the lines of not having the right header file imported.
    When you write a 'C' program, you need not declare your functions. The problem with this is that if you do not declare your functions, the compiler will use as the default return type "int".

    That is why when you post 'C' code, you need to post all of the code, including all the headers. For example, there is a huge difference in this C program if the header is not included:
    Code:
    int main()
    {
        double x = sqrt(10);
    }
    Code:
    #include <math.h>
    
    int main()
    {
       double x = sqrt(10);
    }
    You say "what makes this different"? The answer is the header file <math.h>. When math.h is not included, the compiler assumes that sqrt() is a function returning an int. But in reality, the function returns a double. What can happen? A crash due to a corrupt stack.

    The <math.h> declares the sqrt() function as returning a double and taking a double as the argument. This forces the 'C' compiler to do the compile check to make sure 1) the correct object code is generated with respect to the return type of double, and 2) the arguments you're passing are the right type and the right number.

    For example, this program compiles just fine:
    Code:
    int main()
    {
        double x = sqrt(10, 3, 5, 5);
    }
    What happens when you run it? Who knows.

    That's why when 'C' was first developed, these errors existed all over the place in practically every non-trivial app. That's why function prototypes made it into 'C' in a later revision of the language (but still not mandatory) -- the bugs were literally making 'C' programmers have sleepless nights.

    However, for C++, it is a requirement that all functions are declared and/or defined before you call them. You can't make this mistake in a C++ program.

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Dec 2007
    Posts
    10

    Re: qsort help

    I'm using header files:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <string.h>
    I thought strdub was part of string.h.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured