简体   繁体   中英

C++ - Unexpected output from std::string

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;
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM