in the following code reverse
function rerturns an empty string. no compilation errors.
what can cause the problem here?
#include <iostream>
#include <bits/basic_string.h>
using namespace std;
string reverse(string str) {
string r;
for (int i=str.length()-1; i>=0; i--) {
r[str.length() - 1 - i] = str[i];
}
return r;
}
int main() {
string str = "ABCDefgh";
cout<<"Reverse string is : "<<reverse(str)<<endl;
return 0;
}
Edit: r[str.length() - i] = str[i];
r[str.length() - 1 - i] = str[i];
Your function is invoking UNDEFINED BEHAVIOR, as you are not allocating any memory for the r
string before using its []
operator to assign characters to r
. std::string::operator[]
does not perform any bounds checking, so you are actually trashing surrounding memory. Also, you are not indexing into r
correctly, too (your indexing is off by 1).
Had you used the std::string::at()
method instead of the operator[]
, it would have raised a runtime exception complaining about you accessing characters out of bounds.
You need to make a copy of the input str
first, and then you can reverse the characters of that copy, eg:
std::string reverse(std::string str) {
std::string r = str; // <-- COPY HERE
for (int i = str.length()-1, j = 0; i >= 0; --i, ++j) {
r[j] = str[i];
}
return r;
}
Alternatively, you can use the std::string::resize()
method to pre-allocate the r
string, then use of operator[]
will be valid:
std::string reverse(std::string str) {
std::string r;
r.resize(str.length()); // <-- ALLOCATE HERE
for (int i = str.length()-1, j = 0; i >= 0; --i, ++j) {
r[j] = str[i];
}
return r;
}
Or, you can use the std::string::push_back()
method instead (optionally with the std::string::reserve()
method to avoid re-allocations while pushing):
std::string reverse(std::string str) {
std::string r;
r.reserve(str.length()); // <-- OPTIONAL
for (int i = str.length()-1; i >= 0; --i) {
r.push_back(str[i]);
}
return r;
}
Or, have a look at replacing your manual loop with the std::reverse_copy()
algorithm instead:
#include <algorithm>
std::string reverse(std::string str) {
std::string r;
r.resize(str.length());
std::reverse_copy(str.begin(), str.end(), r.begin());
return r;
}
#include <algorithm>
#include <iterator>
std::string reverse(std::string str) {
std::string r;
r.reserve(str.length()); // <-- OPTIONAL
std::reverse_copy(str.begin(), str.end(), std::back_inserter(r));
return r;
}
However, that being said, since the input str
is being passed by value, it is ALREADY a copy of whatever string you pass to your function, so you don't actually need the local r
string at all. You can reverse the characters of the input str
in-place, just be use to take into account that the source and destination strings are the same string, so adjust your loop accordingly:
std::string reverse(std::string str) {
int count = str.length() / 2;
for (int i = 0, j = str.length()-1; i < count; ++i, --j) {
char ch = str[i];
str[i] = str[j];
str[j] = ch;
// alternatively:
// std::swap(str[i], str[j]);
}
return str;
}
Or, have a look at the std::reverse()
algorithm instead:
#include <algorithm>
std::string reverse(std::string str) {
std::reverse(str.begin(), str.end());
return str;
}
Or, you can use the std::string
constructor that takes 2 iterators as input, as std::string
has reverse iterators available:
std::string reverse(std::string str) {
return std::string(str.rbegin(), str.rend());
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments