C ++-std :: string

时间:2019-04-05 13:01:18

标签: c++ c++11 c++14 c++17

我正在编写一个返回字符串的函数。但是发生了一些奇怪的事情。 result字符串的输出在控制台中被打印为意外内容。

根据机器(已测试),它会变成中文或其他字样或空字符串。但这仅在输入字符串超长时发生。通常适用于较小尺寸的字符串。

是否有更好的方法将char附加到字符串?这是因为我怀疑问题是由我在字符串末尾添加字符的方式引起的。

从控制台

enter image description here

来自调试器

enter image description here

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

1 个答案:

答案 0 :(得分:6)

表达式char* ptr = &sub[0];为您提供了指向char的指针。但是,执行sub += s[i];时,您可能需要string的内部存储空间才能容纳新字符。如果您继续添加它,最终它将发生。这将使ptr无效并使它在重新分配之前无法使用。

当确实发生了这样的重新分配时,将分配较大的缓冲区,则将先前的值从较短的缓冲区移至较大的缓冲区,然后将较短的缓冲区销毁以替换为较大的缓冲区。但是ptr仍然指向以前的较短缓冲区的数据所在的位置。现在它指向一个被破坏对象的元素。然后,当您执行string temp = ptr;时,可能会从无效指针初始化string,这是未定义的行为。

一个相对简单的解决方案是坚持使用索引而不是指针。只要它们在string的大小范围内,就其性质而言,这些索引不会无效。另一种可能的解决方案可能是使用reserve来预先分配足够大的容量,而不必重新分配。