【问题标题】:Weird behavior while converting a std::string to a LPCSTR将 std::string 转换为 LPCSTR 时的奇怪行为
【发布时间】:2012-07-07 09:42:21
【问题描述】:

当我在将 std::string 转换为 LPCSTR 时偶然发现一种奇怪的行为时,我正在玩一些字符串。

我写了一个小测试应用来演示:

#include <string>
#include <Windows.h>
#include <iostream>

using namespace std;

int main ()
{
    string stringTest = (string("some text") + " in addition with this other text").c_str(); 
    LPCSTR lpstrTest= stringTest.c_str();
    cout << lpcstrTest << '\n';

    cout << (string("some text") + " in addition with this other text").c_str() << '\n';

    LPCSTR otherLPCSTR= (string("some text") + " in addition with this other text").c_str();
    cout << otherLPSTR;
}

这是输出:

some text in addition with this other text
some text in addition with this other text
îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþ...[more unreadable stuff]...

我只是想知道是什么导致了这种奇怪的行为。

谢谢

【问题讨论】:

  • 看起来你用添加创建了一个临时对象,然后在它上面调用c_str()并使用那个指针,当临时对象消失时它就失效了。
  • @BoBTFish 正确,具体指stringTest的初始化。
  • 哈哈,那么简单的问题。一直认为c_str() 返回的是一个值,而不是一个指针。谢谢。

标签: c++ string type-conversion stdstring lpcstr


【解决方案1】:

c_str()返回的指针只有在其字符串对象存在时才有效。

// A copy of a temporary string is made here. The temporary is destructed 
// but stringTest stays in scope until the end of main
string stringTest = (string("some text") + " in addition with this other text").c_str();

LPCSTR lpstrTest= stringTest.c_str();
cout << lpcstrTest << '\n';

// the temporary is in scope until the end of the full expression, so this is fine.

cout << (string("some text") + " in addition with this other text").c_str() << '\n';

// But this isn't. At the end of the line, the temporary string object is long gone.
// otherLPCSTR now points to deallocated memory.
LPCSTR otherLPCSTR= (string("some text") + " in addition with this other text").c_str();

// And here you're accessing that memory.
cout << otherLPSTR;

【讨论】:

    【解决方案2】:

    由表达式创建的临时对象将一直存在,直到完整表达式的评估完成为止。一旦对完整的表达式求值,它的所有临时变量都会自动销毁。

    这就是发生的事情

    LPCSTR otherLPCSTR = 
      (string("some text") + " in addition with this other text").c_str();
    

    在此语句之后,临时对象立即被销毁,otherLPCSTR 最终指向死内存。

    在第一种情况下,stringTest 不是临时的。它一直存在到main 的末尾,这意味着lpstrTest 指针仍然有效。

    在第二种情况下,临时 std::string 对象在它还活着的时候立即用于输出。

    只有在第三种情况下,您才尝试存储指针,如上所述,该指针会失效。

    【讨论】:

      【解决方案3】:
      LPCSTR otherLPCSTR= (string("some text") + " in addition with this other text").c_str();
      cout << otherLPSTR;
      

      部分

       (string("some text") + " in addition with this other text")
      

      创建一个所谓的“临时”对象,该对象没有名称,并在包含它的语句完成时被破坏。您从中获得 c_str() ,它指向该临时对象的一些内部存储。您将 c_str() 分配给 otherLPCSTR 变量。之后,“包含临时字符串的语句”已经完成,因此临时字符串被破坏,其他LPCSTR指向“无处”。

      【讨论】:

        猜你喜欢
        • 2010-11-15
        • 1970-01-01
        • 1970-01-01
        • 2016-03-02
        • 1970-01-01
        • 2012-06-01
        • 2012-07-26
        • 2011-04-22
        • 1970-01-01
        相关资源
        最近更新 更多