我是一名经验丰富的编码员,但我仍然是STL的新手,并且刚遇到这个问题:
据我所知,STL容器并不意味着复制它们包含的对象,或者影响它们的生命周期,但实验上我看到了不同的结果.
特别是,如果它们在超出范围之前存储在容器中,则仍然可以访问字符串类,这些类用于在销毁时将其底层存储的第一个字符清零.例如,请考虑以下示例:
using namespace std;
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;
}
Run Code Online (Sandbox Code Playgroud)
当genStr()退出时字符串超出范围,我希望printf只输出"Retval is:",或者至少调用useStr()来给出未定义的结果,因为内存被踩到了通过额外调用的重复分配,但两者都返回适当存储的字符串,而不会失败.
我想知道为什么会这样,但取而代之的是,我很高兴知道我是否可以依赖任何旧物体发生的这种效应.
谢谢
据我所知,STL容器并不意味着复制它们包含的对象
好的,我们就在那里停下来.STL容器不复制它们的内容,频频.它们在插入时复制它们,它们在容器自动或显式调整大小时复制它们,并在复制容器本身时复制它们.很多很多的复制.
我不知道你在哪里知道STL容器不会复制它们的内容.我能想到的唯一接近的是,如果你将一个指针插入一个STL容器,它将复制指针本身而不是指向数据.
此外,您的代码中没有涉及任何引用,所以我对这个问题的标题所引用的内容感到困惑.
STL容器不是要复制它们包含的对象
STL是所有关于复印.它会在您插入对象时生成它们,并且有时在底层存储调整大小时生成它们.如果要复制的对象在函数超出范围时失效(例如,如果添加指向局部变量的指针,而不是复制局部变量),则可能会损坏代码.
在您的情况下,您没有复制对字符串的引用,而是复制字符串.这个复制的字符串然后存在于strQueue的范围内,因此您看到的行为是完全有效和可靠的.
这是另一个误解清除:
特别是字符串类,它意味着在销毁时将其底层存储的第一个字符清零
C++并不倾向于做那种事情.这将是一个隐藏的成本,C++讨厌隐藏的成本:)字符串析构函数不会触及内存,因为一旦析构函数退出,该对象就不再存在.访问它是未定义的行为,因此C++实现将在定义良好的代码中做最快和最少浪费的事情.
| 归档时间: |
|
| 查看次数: |
1432 次 |
| 最近记录: |