【发布时间】:2026-02-01 20:10:01
【问题描述】:
我是一名经验丰富的编码员,但对 STL 还是比较陌生,并且刚刚遇到这个问题:
据我所知,STL 容器并不意味着复制它们所包含的对象,或者以其他方式影响它们的生命周期,但在实验中我看到了不同的结果。
特别是,如果字符串类在超出范围之前存储在容器中,则它们在销毁时将其底层存储的第一个字符清零,仍然可以访问它们。例如,考虑以下示例:
使用命名空间标准;
queue<string> strQueue;
const char *genStr(int i)
{
ostringstream os;
os << "The number i is " << i;
strQueue.push(os.str());
return strQueue.back().data();
}
void useStr()
{
while(!strQueue.empty())
{
cout << strQueue.front() << endl;
strQueue.pop();
}
}
int main(int argc, char **argv)
{
for(int i = 0; i < 40; i++)
{
printf("Retval is: %s\n", genStr(i));
}
useStr();
return 0;
}
当 genStr() 退出时字符串超出范围,我希望 printf 只输出“Retval is:”,或者至少调用 useStr() 会给出未定义的结果,因为内存被额外调用的重复分配压得喘不过气来,但两者都返回适当的存储字符串,没有失败。
我想知道为什么会发生这种情况,但除此之外,我很高兴知道我是否可以依赖任何旧对象发生的这种效果。
谢谢
【问题讨论】:
-
我想补充,不要返回 const char*。使用 std::string 和 std::cout。这就是他们的目的。在我看来,您正处于从 C 转换为 C++ 的过程中。字符串类不应该做任何将它们的第一个字符归零的事情。那将是一个 C 主义。在 C++ 中,安全性遥遥领先。
-
感谢您的建议 - 我通常使用 std::string 和 std::cout (正如您在 useStr 中看到的那样),printf 并返回 const char * 只是为了证明而惊慌失措对我自己来说,基础数据仍然很好,我可以依赖它。