C++ 指向向量和向量的指针中的循环迭代
我的密码是C++ 指向向量和向量的指针中的循环迭代,c++,C++,我的密码是 //Pointer to a Vector std::vector<int> *ptr = new std::vector<int>; ptr->push_back(20); ptr->push_back(30); ptr->push_back(40); std::vector<int>::const_iterator pend = ptr->end(); for(std::vector<int>::const
//Pointer to a Vector
std::vector<int> *ptr = new std::vector<int>;
ptr->push_back(20);
ptr->push_back(30);
ptr->push_back(40);
std::vector<int>::const_iterator pend = ptr->end();
for(std::vector<int>::const_iterator it = ptr->begin(); it != pend; ++it){
cout<<*it<<endl;
}
ptr->clear();
delete ptr;
pend = ptr->end();
for(std::vector<int>::const_iterator it = ptr->begin(); it != pend; ++it){
cout<<*it<<endl;
}
//Normal Vector
std::vector<int> nptr= {20,30,40};
std::vector<int>::const_iterator end = nptr.end();
for(std::vector<int>::const_iterator it = nptr.begin(); it != end; ++it){
cout<<*it<<endl;
}
nptr.clear();
end = nptr.end();
for(std::vector<int>::const_iterator it = nptr.begin(); it != end; ++it){
cout<<*it<<endl;
}
当您调用
删除ptr代码>您正在取消分配为指针对象保留的内存。然后执行pend=ptr->end()代码>这肯定会调用未定义的行为,因为您没有任何指向的std::vector
最佳做法是在删除指针时将其值设置为NULL。因为删除时,删除的是指向的对象,而不是指针的内容。因此指针仍然指向相同的内存位置。当您将它设置为NULL以防有人再次尝试使用它时,他们会知道指针不指向任何内容
ptr = nullptr;
当您在ptr
上调用delete
时,请务必记住在取消引用指针之前执行空检查,因为您正在销毁向量及其所有元素
取消对已删除指针的引用(即*ptr
或ptr->
)是未定义的行为
删除对象时,它指向的内存不一定消失(如果不再使用整个内存页,它可能不再可访问),因此取消对指针的引用可能不会导致崩溃。在您的特定环境中,内存似乎不会立即被覆盖(某些环境会立即覆盖释放的内存,例如visual studio调试构建),向量的内部状态会保留足够多,以便循环仍能打印4个值(可能是删除前向量的容量)。但是,您不能依赖此行为,它可能会打印0个值、1000个值、崩溃或任何其他未定义的行为。您有什么问题?您删除ptr
,然后调用ptr->end()
,显然这是未定义的行为。我的问题很简单,为什么删除后循环会迭代。delete是指获取与向量相关的内存吗?那么您的问题是“为什么未定义的行为以这种方式而不是那种方式表现”?答案是“不知道它会做什么”。它可以不输出,可以输出任何可以想象的奇怪的输出,可以使程序崩溃,或者做任何其他事情。在这种情况下,没有规则告诉编译器它必须做什么,因此思考它为什么要这样做是没有意义的。这就是为什么人们不喜欢未定义的行为;这是不可靠的和不可携带的;第一种方法清除并销毁向量,然后继续使用它(由于向量不存在,因此未定义),而第二种方法仅清除向量。请将您的评论中的问题添加到问题中。目前还不清楚这个问题是关于什么的,只阅读问题请使用nulltptr而不是NULL。我已经看到了这一点。使用nullptr比使用NULL有什么好处?NULL
通常只是#定义NULL 0
nullptr
是一个明确的空指针,只能分配给指针类型。NULL只是一种表示0的奇特方式。nullptr无法分配给int。您可以将其分配给bool,但通常从bool到int的转换不适用于nullptr。谢谢!编辑答案
ptr = nullptr;