qsort() and std::vector

G

gallows

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.
 
V

Victor Bazarov

gallows said:
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
 
M

Mike Wahler

gallows said:
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
 
G

gallows

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.
 
M

Marcus Kwok

Victor Bazarov said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top