qsort() and std::vector

Discussion in 'C++' started by gallows, Jan 20, 2007.

  1. gallows

    gallows Guest

    I've tried to use C qsort() on an object derivate by std::vector, but
    it doesn't work.

    I've the follow structure:

    struct Item {
    std::string name;
    int number;
    }


    And the class "Container":

    class Container : public std::vector<Item> { /* ... */ }

    sort method is the follow:

    void Container::sort()
    {
    qsort(this, this->size(), sizeof(Item), compare_items_by_name);
    }

    compare function is:

    int compare_items_by_name(const void* p, const void* q)
    {
    return static_cast<const
    Item*>(p)->name.compare(static_cast<const Item*>(q)->name);
    }

    My compiler (g++ 4.1) doesn't give warnings nor errors, but:

    Program received signal SIGSEGV, Segmentation fault.
    0xb7ee700e in std::string::compare () from /usr/lib/libstdc++.so.6

    I can't find the mistake, maybe in the casting?

    Thanks a lot!

    s.
    gallows, Jan 20, 2007
    #1
    1. Advertising

  2. gallows wrote:
    > I've tried to use C qsort() on an object derivate by std::vector, but
    > it doesn't work.


    It's not a good idea, probably, anyway.

    > I've the follow structure:
    >
    > struct Item {
    > std::string name;
    > int number;
    > }


    ;

    >
    > And the class "Container":
    >
    > class Container : public std::vector<Item> { /* ... */ }
    >
    > sort method is the follow:
    >
    > void Container::sort()
    > {
    > qsort(this, this->size(), sizeof(Item), compare_items_by_name);
    > }
    >
    > compare function is:
    >
    > int compare_items_by_name(const void* p, const void* q)
    > {
    > return static_cast<const
    > Item*>(p)->name.compare(static_cast<const Item*>(q)->name);
    > }
    >
    > My compiler (g++ 4.1) doesn't give warnings nor errors, but:
    >
    > Program received signal SIGSEGV, Segmentation fault.
    > 0xb7ee700e in std::string::compare () from /usr/lib/libstdc++.so.6
    >
    > I can't find the mistake, maybe in the casting?


    The mistake is that 'qsort' uses whatever implementation-defined
    mechanism for swapping the two values it thinks are out of order.
    It only works with POD. Since your 'Item' has 'std::string' as
    a member, it's not a POD.

    Use 'std::sort'. It's just as quick as 'qsort' and is much, much
    better when it comes to containers.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jan 20, 2007
    #2
    1. Advertising

  3. gallows

    Mike Wahler Guest

    "gallows" <> wrote in message
    news:...
    > I've tried to use C qsort() on an object derivate by std::vector, but
    > it doesn't work.
    >
    > I've the follow structure:
    >
    > struct Item {
    > std::string name;
    > int number;
    > }
    >
    >
    > And the class "Container":
    >
    > class Container : public std::vector<Item> { /* ... */ }


    Try to avoid inheriting from standard containers.
    They don't have virtual destructors. For what you're
    showing, containment will do.

    >
    > sort method is the follow:
    >
    > void Container::sort()
    > {
    > qsort(this, this->size(), sizeof(Item), compare_items_by_name);
    > }
    >
    > compare function is:
    >
    > int compare_items_by_name(const void* p, const void* q)
    > {
    > return static_cast<const
    > Item*>(p)->name.compare(static_cast<const Item*>(q)->name);
    > }
    >
    > My compiler (g++ 4.1) doesn't give warnings nor errors, but:
    >
    > Program received signal SIGSEGV, Segmentation fault.
    > 0xb7ee700e in std::string::compare () from /usr/lib/libstdc++.so.6
    >
    > I can't find the mistake, maybe in the casting?
    >
    > Thanks a lot!


    Don't use 'qsort()'. Use 'std::sort'

    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>

    struct Item
    {
    Item(const std::string& n, int i)
    : name(n), number(i) { }

    std::string name;
    int number;
    };

    bool comp(const Item& I1, const Item& I2)
    {
    return I1.name < I2.name;
    }

    class Container
    {
    std::vector<Item> v;
    public:
    void sort()
    {
    std::sort(v.begin(), v.end(), comp);
    }

    void append(const Item& i)
    {
    v.push_back(i);
    }

    void show(const std::string& prefix = "") const
    {
    std::cout << prefix;
    std::vector<Item>::const_iterator it(v.begin());
    std::vector<Item>::const_iterator en(v.end());
    for(; it != en; ++it)
    std::cout << it->name << '\t' << it->number << '\n';
    }
    };

    int main()
    {
    Container c;
    c.append(Item("XYZ", 42));
    c.append(Item("ABC", 25));
    c.append(Item("JKL", 10));
    c.append(Item("PQR", 6));
    c.append(Item("DEF", 0));

    c.show("unsorted:\n");
    c.sort();
    c.show("sorted:\n");

    return 0;
    }

    -Mike
    Mike Wahler, Jan 20, 2007
    #3
  4. gallows

    gallows Guest

    Mike Wahler ha scritto:

    >
    > Try to avoid inheriting from standard containers.
    > They don't have virtual destructors. For what you're
    > showing, containment will do.
    >


    Ok, I will do.

    >
    > Don't use 'qsort()'. Use 'std::sort'
    >
    > -- cut --
    >
    > -Mike


    Oh thanks, it's perfect. Understood.
    gallows, Jan 21, 2007
    #4
  5. gallows

    Marcus Kwok Guest

    Victor Bazarov <> wrote:
    > Use 'std::sort'. It's just as quick as 'qsort'


    Even better, std::sort may be faster than qsort due to better inlining
    of the comparison function.

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
    Marcus Kwok, Jan 22, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jonathan Mcdougall

    Clarification for std::vector and std::map

    Jonathan Mcdougall, Jul 30, 2003, in forum: C++
    Replies:
    5
    Views:
    417
    Sir_Ciph3r
    Jul 31, 2003
  2. Anonymous
    Replies:
    20
    Views:
    4,273
    Pete Becker
    Mar 30, 2005
  3. Jason Heyes
    Replies:
    8
    Views:
    709
    Andrew Koenig
    Jan 15, 2006
  4. Replies:
    8
    Views:
    1,894
    Csaba
    Feb 18, 2006
  5. Rune Allnor
    Replies:
    4
    Views:
    928
    Rune Allnor
    Dec 11, 2008
Loading...

Share This Page