Rya*_*yan 0 c++ memory-management vector
我通过将它的内存分配给堆来创建了一个向量.然后我创建10个字符串对象也分配给堆内存并将它们存储在向量中.我试图使用delete运算符释放与每个新字符串对象关联的内存,但我不是如何做到的.我正在使用C++ 11.
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<string> *v = new vector<string>;
for(int i = 0; i < 10; i++) {
// allocate a new string object on the heap
string *a = new string("Hello World");
//de-reference the string object
v->push_back(*a);
}
// show the contents of the vector
for(auto i = v->begin(); i != v->end(); ++i) {
// okay so this makes a lot more sense than:
// const string &s = *i;
// this way we create a pointer to a string object
// it is a lot more clear this way
const string *s = &(*i);
cout << *s << " " << s->length() << endl;
}
cout << endl << endl;
for(vector<string>::iterator it = v->begin(); it != v->end(); ++it) {
delete ⁢
v->erase(it);
}
for(auto i = v->begin(); i != v->end(); ++i) {
cout << *i << endl;
}
cout << endl << "Size: " << v->size() << endl;
delete v;
}
Run Code Online (Sandbox Code Playgroud)
g++ -std=c++11 main.cc -o main
我的错误是并非所有对象都被删除.我最后在最后4个语句后留下了5个对象.一旦完成这些操作,我希望向量内部有零个对象.
我的输出:
Hello World 11
Hello World 11
Hello World 11
Hello World 11
Hello World 11
Hello World 11
Hello World 11
Hello World 11
Hello World 11
Hello World 11
Hello World
Hello World
Hello World
Hello World
Hello World
Size: 5
Run Code Online (Sandbox Code Playgroud)
问题是并非所有对象都被删除.
我认为你在无数问题中担心的特殊问题是你的for循环不是删除所有项目,即:
for(vector<string>::iterator it = v->begin(); it != v->end(); ++it) {
delete ⁢
v->erase(it);
}
Run Code Online (Sandbox Code Playgroud)
您的问题是您正在更改正在迭代的向量,这会导致未定义的行为,因为您没有删除所有值.(只要不添加或删除值,向量的迭代器才有效).
我可以解释为什么它只做5,但答案不是跨平台的.在这种情况下,编译器可以随意做任何事情.对于编译器来说,让恶魔飞出你的鼻子同样有效.
基本上,你正在删除一个值,然后他们移动到下一个索引.所以你在0处删除了什么,它会将1处的值拉到0处.然后你移动到索引1,它包含以前在索引2中的内容.然后你删除它.基本上,您从向量中删除所有偶数索引.
编辑:将问题减少到最小可重现性:
std::vector<int> vals;
for (int i = 0; i < 11; i++0) vals.push_back(i);
for (std::vector<int>::iterator i = vals.begin(); i != vals.end(); ++i)
{
vals.erase(i);//after this point, i's behavior is undefined!
}
Run Code Online (Sandbox Code Playgroud)
编辑3:使用代码枚举所有问题(基于Meta对话的建议操作)
new std::string将简单地分配指向字符数组的指针和堆中的大小.所以这也值得注意.std::vector<T*>.std::vector<T>将是一个实例的向量T.std::string& s = *it比获取地址更具可读性.&it是类型的std::vector<string>::iterator*.为什么这可能不会崩溃和烧毁的是迭代器类型只包含内置类型,并且在此之后你没有做太多(你可能已经为自己设置了一些美味的堆栈损坏).如果你有一个std::vector<T*>(匹配的项目1)具有唯一所有权的向量,你想要这样做来清理它:delete &(*it);
但做一些类似的东西会更好std::vector<std::unique_ptr<T>>,从不担心它.
| 归档时间: |
|
| 查看次数: |
3229 次 |
| 最近记录: |