C ++ - std :: string :: ~string()字符串仍然可以打印为空值

时间:2014-03-05 18:30:52

标签: c++ string

当我和std::string合作时,我决定做以下事情:

int main(int argc, char **argv)
{
    std::string s = "Hello World";
    s.~basic_string();
    std::cout << s.c_str();
}

然而,它打印没有,并且没有垃圾。但是,在 my basic_string类中,当调用析构函数时,我会得到垃圾。 std::string如何处理这个问题?我的使用了allocatorconstructdestroyallocatedeallocate,但它仍然不起作用。

注意:我不是在寻找我的类的解决方案,而是要了解std::string如何做到这一点。

3 个答案:

答案 0 :(得分:5)

首先,除非在极少数特定情况下,否则不应显式调用析构函数,这不是其中之一。当字符串超出范围时,将根据标准自动调用析构函数。

其次,在使用被破坏的对象时,您对垃圾的期望是什么?这是应该避免的未定义行为。如果你想限制范围,那么使用花括号然后创建一个子范围,并导致调用对象析构函数和要清理的东西。

int main(int argc, char **argv)
{
    { // new scope
      std::string s = "Hello World";
      std::cout << s;
    } // s destructor called for you

  // other stuff
}

答案 1 :(得分:0)

在生命周期结束的对象上调用析构函数是未定义的行为。 std::string有一个非平凡的析构函数,所以当它超出范围时,它的生命周期已经结束。自动调用的析构函数应该导致双重自由错误。因为它是未定义的行为,所以没有任何保证。

Does explicitly calling destructor result in Undefined Behavior here?详细介绍了这一点。

答案 2 :(得分:-1)

虽然它是未定义的行为,因为对象被破坏但我可以猜出场景背后发生了什么。

当类型std::basic_string的对象为空时,以下结构s [0]有效。例如

std::string s;

std::cout << s[0];

在这种情况下,该类返回对char类型的对象的引用,该对象初始化为零。所以似乎该类包含具有值char(0)的数据成员。因此,当没有分配内存时,即当对象为ampty时,类例会在调用c_str()时返回指向此数据成员的指针。

所以似乎释放早期分配的内存后的析构函数将相应的指针设置为NULL。当您调用函数c_str()时,它会检查指针是否等于NULL。如果是,则返回指向我所描述的数据成员的指针。

它可能是您正在寻找的解决方案。:)