所有的容器只要empty了,对它们的元素操作都会出错。这一点还必须遵守设计者的要求,C/C++里要强行搞死什么东西,都不是很难的事。
在C++里,大多数使用限制都是靠自觉的;不过,一般的设计者都应改进行基本的断言判断,只是一般用于入参的检测。
所以,个人觉得应该是:
“方法2”最好,最符合用C++;
“方法1”实现者没有assert也可以理解和无可厚非;
“方法3”可能是作者自己过头了。
自己今天碰到的问题:
typedef struct ReadFileOffsettag
{
int time;
LONG offset;
}ReadOffset;
vector<ReadOffset> StoreEachReadInfoVec
(第一种方法)
vector <ReadOffset>::iterator iter,iend; //起始和末尾迭代器值
iend = StoreEachReadInfoVec.end();
int j;
for (iter = StoreEachReadInfoVec.begin(),j = 0;iter != iend; /*iter++,*/j++)
{
if (CurrentRead.offset == iter[j].offset) //比较若相等就把此项对应的offset赋值给CurrentRead.offset,删除下一项
{
CurrentRead.offset = iter[j].offset;
StoreEachReadInfoVec.erase(iter + j);
}
}
#if 0(第二种方法)
int size = StoreEachReadInfoVec.size();
for(int i = 0;i < StoreEachReadInfoVec.size() ;i++)
{
int offsettt = StoreEachReadInfoVec[i].offset;
if (CurrentRead.time == StoreEachReadInfoVec[i].time)
{
CurrentRead.offset = StoreEachReadInfoVec[i].offset;
//StoreEachReadInfoVec.erase();
StoreEachReadInfoVec.pop_back();
}
}
#endif
Google:
http://www.programfan.com/club/showpost.asp?id=16874
| ||
|
http://blog.vckbase.com/panic/archive/2005/08/05/10513.aspx
vector::pop_back,错误延迟发生
作者: Panic 2005年8月5日
pop_back是vector中一个不常用的成员函数,功能是销毁并抛弃vector的最后一个元素。
msdn已经明确要求调用这一函数的vector必须非空。但是如果对空vector调用会发生什么呢?
pop_back调用一般并不会引起程序立刻异常或崩溃,vector只是简单的把存储区前面的一段内存看作一个“元素”,对它调用析构函数,然后尾迭代器向前移动1。
由于存储区的前一段内存一般而言也是有效的,可访问的空间,所以这个操作可能只是修改了不应该修改的数据而已。一般不会立刻发现问题。
那么问题在什么时候发生呢?析构的时候!
析构的时候,vector销毁首元素,然后增加首迭代器直到它等于尾。但是由于前面的pop_back,尾迭代器位置前移,在最开始就已经等于甚者小于首。所以这个移动其实是对后面内存空间的一次大清理。程序会因此长时间失去响应。
而当vector是一个临时变量(栈对象)的时候,因为栈对象清理的工作是在后台操作,所以在我们看来往往是函数退出的时候突然死掉了。
因为错误发生的地点和检查到错误的地点相隔比较远,所以这无疑是一个比较难找的错误。
解决方法:
方法1,修改vector的实现代码,在pop_back中加入断言。这么做一劳永逸,不过很多人不愿意:P
方法2,调用pop_back前进行断言或者判断。这个完全靠使用者自觉。
方法3,避免在代码中调用pop_back。嗯,好办法--b