Sam Smith
Sam Smith

Reputation: 31

Proper use of std::sort in c ++

for example I have a string data with the following contents

std :: string words {"armando dippet"};

if using

words.begin () / end () then it works,

but if

std :: string words [] {"gandalf", '"harry", "malfoy", "ron"}

using

std::sort(words.begin () / end ())

does not work, but must be changed to

std :: sort (std :: begin (words), std :: end (words))

or

std :: sort (words, words + sizeof ( words) / sizeof (words [0]))

in order to run, then I switched to dynamic strings

std :: string * words {new std :: string [2] {"hermione", "aziz"}}

using

std::sort(std :: begin (words) / end (words))

didn't work, using

std::sort(words-> begin () words -> end ())

is successful but the result is not suitable, using

std :: sort (words, words + sizeof (words) / sizeof (words [0]))

is successful

To be honest, I'm confused about the use of sort

Upvotes: 0

Views: 385

Answers (2)

eerorika
eerorika

Reputation: 238491

std :: string * words {new std :: string [2] {"hermione", "aziz"}}
std :: sort (words, words + sizeof (words) / sizeof (words [0]))

is successful

It is "successful" in the sense that the types of the arguments are iterators, and therefore well-formed.

But the pointer arithmetic on your end pointer is wrong and depending on the size of std::string it could go beyond the array resulting in undefined behaviour (in general case; not necessarily in this one), or it could result to the beginning and nothing is sorted, or anything in between. In short, the calculation is no related to the length of the array in any way.

Here is a correct version:

std::sort(words, words + 2);

P.S. Avoid using owning bare pointers.

Upvotes: 1

Caleth
Caleth

Reputation: 63402

Going backwards

std::string * dynamic_length {new std :: string [2] {"hermione", "aziz"}};

Pointers are not arrays. They don't have a length, so you will have to record that elsewhere.

std::sort(dynamic_length, dynamic_length + 2);

Arrays lack methods. They are only an contiguous sequence of values. The array type holds the length.

std::string static_length[] {"gandalf", '"harry", "malfoy", "ron"}; // declares a std::string[4]

There is an implicit conversion from array to pointer.

std::sort(static_length, static_length + 4);

std has a pair of function templates that operate on arrays (and have other overloads)

std::sort(std::begin(static_length), std::end(static_length));

begin simply does the array to pointer conversion. end additionally adds the length, taken from the type.

template <typename T, size_t N>
T * end(T(&arr)[N]) // this is the syntax for passing an array reference
{ return arr + N; }

What you should be using is an actual container, such as std::vector<std::string>

std::vector<std::string> words {"gandalf", '"harry", "malfoy", "ron"};

This has members begin and end, overloads for the free function begin and end, and others

std::sort(words.begin(), words.end()); // member
std::sort(std::begin(words), std::end(words)); // free function
std::sort(words.data(), words.data() + words.size()); // vector converts to pointer too

Upvotes: 2

Related Questions