VC ++函数字符串:: c_str():第一个字节的地址被设置为0(比较克++)(VC++ fun

2019-10-29 12:00发布

我试图让一个字符串的函数的结果时,遇到了一个奇怪的问题c_str()其结果是相克不一致++。

有一个名为Test返回一个字符串实例功能。 我想使用char*类型来存储结果(它的需要)。 正如你所看到的函数是简单的返回一个字符串“resultstring”。 但是,当我试图得到的结果奇怪的事情发生。

我得到的结果是“”的两部分。 在第一部分和第三部分都返回“resultstring”。 虽然这是在Visual Studio。 用克编译相同的代码的三个部分++都返回“的结果字符串。 让我们只以及第一个看到的结果是:

地址:16841988

resultstring

地址:16842096

“这里是一个空行”

地址:16842060

地址:16842144

地址:16842396

地址:16842396

resultstring

地址:5705156

resultstring

地址:5705156

resultstring

地址:5705156

地址:5705196

地址:5705156

地址:5705156

resultstring

代码如下非常简单的列表:

#include <iostream>
#include <string>
using namespace std;

string Test()
{
     char a[64] = "resultstring";
     return  string(a);
}
int main(void)
{
    //part one
    cout << "address:"<< (unsigned)Test().c_str() << endl;
    cout << Test().c_str() << endl;

    //part two
    char *j  = const_cast<char*>(Test().c_str());
    cout << "address:"<< (unsigned)Test().c_str() << endl;

    cout << j << endl;
    cout << "address:" << (unsigned)j <<endl;

    //part three
    string h3 = Test();
    char* j2 = const_cast<char*>(h3.c_str());
    cout << "address:"<< (unsigned)Test().c_str() << endl;
    cout << "address:"<< (unsigned)h3.c_str() << endl;

    cout << "address:" << (unsigned)j2 <<endl;
    cout << j2 <<endl;
    getchar();
    return 0;

}


现在我有三个问题。

1,为什么用g符合的结果++返回所有resultstring而Visual Studio中的结果返回所有resultstring除了变量j? 如果您调试到这一点,你会发现,VC ++只设置的地址j200 65 73 75 …这是esultstring00开头的地址。 它是不是奇怪的是,我们会得到“”。 这就像char* str = "\0something else"您总能获得“”。 但问题是,为什么会发生这种情况只与j

第二,为什么的地址之一(unsigned) Test ().c_str()是与别人有什么不同? 如果我们删除行string h3 = Test ()地址将全部相同。

第三,它是Visual Studio的“回”变量值“正确”的行为j ? 为什么它是与G ++有什么不同?

期待您的答复。

问候,凯文·

Answer 1:

您具有不确定的行为。 所述std::string通过返回Test()是一个暂时的,由返回的指针c_str() (存储在j )不再是临时的寿命结束后有效。 这意味着,任何事情都有可能发生。 指针指向可能包含垃圾的阵列,它可以是原始字符串或执行可以具有空终止它的开始。 访问可能会导致分割故障或者它可能允许您访问原始的字符串数据。 这可以与通常不会不同的编译器和标准库的实施方式之间变化。

char *j  = const_cast<char*>(Test().c_str());
// The contents pointed to by j are no longer valid and access that content 
// is undefined behavior
cout << "address:"<< (unsigned)Test().c_str() << endl;

地址是调用之间不同的Test()因为它返回每次调用的时间暂时。 一些编译器可以优化这个和/或数据的分配可以得到的存储器中的相同块,但它不能保证是相同的。



Answer 2:

这是完全错误的。 您创建和每次通话时间摧毁一个临时字符串Test() 任何试图访问使用返回指针内存Test().c_str()之后暂时遭到破坏是没有意义的-记忆已经被释放。 它可能有旧值(如果没有被访问之前写有),但它可能有什么,以及(如果它是在访问之前重复使用)。 这是未定义的行为。

在VC的情况下++是重写一次,而不是在其他情况下。 与海湾合作委员会 - 它从来没有被覆盖。 但是,这是纯属偶然。 再一次 - 这是UB。



文章来源: VC++ function string::c_str(): the address of the first byte was set to 0 (compare to g++)