C++中的 StringStream/c_str() 损坏

StringStream/c_str() corruption in C++

本文关键字:str 损坏 中的 StringStream C++      更新时间:2023-10-16

我在 std::cout、std::stringstream 和 std::string.c_str(( 方面遇到了一些问题。主要是,似乎有些东西被困在某个地方的缓冲区中,我不确定如何解决这个问题。

如果你不喜欢在StackOverflow中阅读代码,这里有我的github的相关链接:TLString 类、Test 类和单元测试 -- 你可以跳到最后,我陈述我更简洁的问题。

在我的单元测试中,我有以下代码:

    Test <std::string> strtest; // A unit test object expecting strings.
    Test <const char*> chtest; // A unit test object expecting const char*s
    // ...
    TurnLeft::Utils::TLString str3("Exterminate.");
    // ...
    /* Basically, name() and expect() will use the passed arg. 
     * in the output in order to
     * display output such as the following:
     * str(): expecting 'Exterminate.' | Actual 'Exterminate.' => PASS
     */
    strtest.name("str()").expect("Exterminate.").test( str3.str() );
    /* To try and determine where the corruption was occuring, I did a 
     * simple cout here, and got what should be the expected result of 
     * the next test,
     * meaning that the actual test should be succeeding.
     */
    std::cout << str3.c_str() << std::endl //outputs Exterminate. normally.
    /* But when I try to invoke that same method (c_str()) within the test
     * object, it simply copies the argument passed in for name().
     */
    chtest.name("c_str()").expect("Exterminate.").test( str3.c_str() );
    // Should output 'Exterminate.' as in the saatement before, but instead
    // outputs 'c_str()'.

下面是 Test 类的代码:

namespace unittest{
static std::string status[2] = {"FAIL", "PASS"};
    template <class ExpectedResult>
    class Test
    {
     private:
        ExpectedResult  expected;
        ExpectedResult  actual;
        std::string     testName;
     public:
        Test();
        Test <ExpectedResult>& expect (ExpectedResult value);
        Test <ExpectedResult>& name   (std::string);
        void test   (ExpectedResult value);
    };
template <class ExpectedResult> Test <ExpectedResult>&
Test<ExpectedResult>::expect(ExpectedResult value)
{    
    expected = value;
    return *this;
}
template <class ExpectedResult>
Test <ExpectedResult>&
Test<ExpectedResult>::name(std::string aName)
{
    testName = aName;
    return *this;
}
    template <class ExpectedResult>
    void Test<ExpectedResult>::test(ExpectedResult value)
    {
        actual = value;
        std::cout << testName << ": ";
        std::cout << "Expecting: " << expected << " | ";
        std::cout << "Actual: " << actual;
        std::cout << " => " << status[actual==expected] << std::endl;
    }

TLString 类是我正在编写的类,它将为C++中的字符串提供更流畅的操作(例如,串联(。它使用字符串流来处理这些操作。TLStream::c_str()方法实际上只是这样做:return stream.str().c_str();

所以,我真的很困惑actual是如何被分配testName值的。我不确定冲突发生在哪里,因为只有当这些变量都输出到 CLI 时,它们才会接近交互,在这种情况下,这两者是不同的数据类型。

我编写了 c_str(( 功能,因为很简单,您永远不知道某些第三方库何时会依赖 C 字符串而不是C++字符串,并且没有理由限制我的类。即使在 std::ios 中,您也需要使用 c 字符串来处理某些事情。

任何帮助将不胜感激。

谢谢!

std::stringstream.str()返回一个类型为 std::string 的临时对象。当TLStream::c_str()返回时,此临时将超出范围,使返回的char const*指针指向释放的内存。

    std::cout << " => " << status[actual==expected] << std::endl;

==将指向字符串文本"Exterminate"const char*与指向str3.c_str()const char*进行比较

这些指针是不同的。

您需要使用类似 strcmp 的东西来比较它们,而不是通过指针相等。