Reputation: 715
I'm writing a function which returns a string. But something weird happened. The output of the result
string was printed as an unexpected thing from the console.
It becomes Chinese or something else or EMPTY STRING depending on the machine (TESTED). But this only happens when the input string is super long. It works normally for strings with a smaller size.
Is there a better way to append char
to a string? It's because I suspect the problem was caused by the way how I added chars to the end of a string.
From Console
From Debugger
main.cpp
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
bool checkPalindrome(string s)
{
return (s == std::string(s.rbegin(), s.rend()));
}
string longestPalindrome(string s)
{
if (s.size() > 1000 || s.empty())
return "";
string result = "";
string sub = "";
char* ptr = &sub[0];
for (int i = 0; i < s.length(); ++i) {
sub += s[i];
while (true) {
string temp = ptr;
if (checkPalindrome(temp)) {
ptr = &sub[0];
if (temp.length() > result.length()) {
result = temp;
break;
}
break;
}
else {
ptr++;
}
if (ptr == &sub[sub.length()-1]) {
ptr = &sub[0];
break;
}
}
}
std::cout << "end of function" << std::endl;
return result;
}
int main()
{
string output = longestPalindrome("babaddtattarrattatddetartrateedredividerb");
std::cout << output << std::endl;
return 0;
}
Upvotes: 3
Views: 517
Reputation: 29022
The expression char* ptr = &sub[0];
gives you a pointer to a char
. However, when you perform sub += s[i];
you may require the string
's internal storage to grow to accommodate the new character. If you keep adding to it, eventually it will happen. This will invalidate ptr
and render it unusable until it's reassigned.
When such a reallocation does happen a larger buffer is allocated, the previous value is moved from the shorter buffer to the larger buffer then the shorter buffer is destroyed to be replaced by the larger one. But ptr
still points to where the previous shorter buffer's data used to be. It's now pointing to an element of a destroyed object. When you then do string temp = ptr;
you risk initializing a string
from an invalidated pointer which is undefined behavior.
One relatively simple solution woult be to stick with indices instead of pointers. Indices by their nature don't get invalidated as long as they are within the bounds of the string
's size. Another possible solution might be to use reserve
to pre-allocate a large enough capacity that it never has to reallocate.
Upvotes: 6