请教:遇到 STL中的vector 的线程安全问题:vector iterator not dereferencable

LeonTown 2007-08-25 05:45:21
如题
我通过push_back向一个vector对象注入了若干int型数据,
并SetTimer(),在Timer函数中,依次取得vector对象中的数据。

发现似乎是到了最后的一个元素时,程序崩溃~
之前的元素都能够正常读取和使用。

错误提示有:vector iterator not dereferencable
查了一下,说是线程安全方面的问题。

SetTimer的确在内部开了线程,但我的这个问题具体是怎么回事呢?

请各位帮忙指点迷津!
谢谢!
...全文
1057 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
LeonTown 2007-08-26
  • 打赏
  • 举报
回复
谢谢关注!
附上主要代码

class CMyPath
{
typedef pair<int,int> myPoint;
vector<myPoint> bob2mePath;
vector<myPoint>::iterator itLoop;

} //class CMyPath


class A1
{
CMyPath* thePath;

fun1()
{
thePath = new CMyPath(eyeBobPt.x, eyeBobPt.y, myPt.x, myPt.y); //参数赋值正常

thePath->itLoop = (thePath->bob2mePath).begin();
//CMyPath类中 itLoop 为vector对象 bob2mePath 的 iterator

eyeStart = true;
SetTimer(4, 10, NULL);
}

OnTimer() //运行时错误发生的函数
{
if(thePath->itLoop != (thePath->bob2mePath).end())
{
//提取使用vector中的元素
bobEyeRect.bottom = thePath->itLoop->second + 80;
bobEyeRect.left = thePath->itLoop->first - 80;
bobEyeRect.right = thePath->itLoop->first + 80;
bobEyeRect.top = thePath->itLoop->second - 80;
InvalidateRect(bobEyeRect, true);
//发现注释掉上面5行,运行虽然没有效果,但不出运行时错误了

(thePath->itLoop)++;
}
else
{
eyeStart = false;
KillTimer(4);
}
}

} //class A1

vector 对象 thePath->bob2mePath 往里插入数据时,没有问题
调试发现插入的数据正常

OnTimer()函数的问题在哪里呢?
谢谢!
iambic 2007-08-25
  • 打赏
  • 举报
回复
也未必和线程有关吧。说不定是你越界读取。
gfxiang 2007-08-25
  • 打赏
  • 举报
回复
贴代码
effective stl pdf 怎么使用stl 这里几乎都有说明 条款1: 仔细选择你要的容器 条款2: 小心对“容器无关代码”的幻想 条款3: 使容器里对象的拷贝操作轻量而正确 条款4: 用empty来代替检查size是否为0 条款5: 尽量使用范围成员函数代替他们的单元素兄弟 条款6: 警惕C++的及其令人恼怒的分析 条款7: 当使用new得指针的容器时,切记在容器销毁前delete那些指针 条款8: 千万不要把auto_ptr放入容器 条款9: 小心选择删除选项 条款10: 当心allocator的协定和约束 条款11: 了解自定义allocator的正统使用法 条款12: 对STL容器的线程安全性的期待现实一些 vector和string 条款13: 尽量使用vector和string来代替动态申请的数组 条款14: 用reserve来避免不必要的内存重新分配 条款15: 当心string的实现的变化 条款16: 如何将vector和string的数据传给传统的API 条款17: 用“交换技巧”来修正过度的容量 条款18: 避免使用vector 关联容器 条款19: 了解相等和等价的区别 条款20: 为包含指针的关联容器指定比较类型 条款21: 永远让比较函数对相等的值返回false 条款22: 避免对set和multiset的键值进行修改 条款23: 考虑用排序的vector代替关联容器 条款24: 当效率很关键时尽量用map::insert代替map::operator 条款25: 让自己熟悉非标准的hash容器 迭代器 条款26: 尽量使用iterator代替const_iterator,reverse_iterator和const_reverse_iterator 条款27: 使用distance和advance把const_iterators转化成iterators 条款28: 了解如何通过reverse_iterator的base得到iterator 条款29: 需要一字符一字符输入时请用istreambuf_iterator 算法 条款30: 确保目的范围足够大 条款31: 了解你的排序选项 条款32: 如果你真的想删除东西的话在remove-like的算法后紧接上erase 条款33: 当心在包含指针的容器使用remove-like的算法 条款34: 注意哪些算法需要排序过的范围 条款35: 通过mismatch或lexicographical_compare实现简单的忽略大小写字符串比较 条款36: 用not1和remove_copy_if来表现copy_if 条款37: 用accumulate或for_each来统计序列 仿函数,仿函数类,函数等等 条款38: 把仿函数类设计成值传递的 条款39: 用纯函数做predicate 条款40: 增强仿函数类的适应性 条款41: 明确ptr_fun, mem_fun和mem_fun_ref的区别 条款42: 保证less是operator<的意思 用STL编程 条款43: 尽量用算法调用代替手写循环 条款44: 尽量用成员函数代替同名的算法 条款45: 注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46: 考虑用函数对象代替函数作为算法的参数 条款47: 避免产生只写代码 条款48: 总是#include适当的头文件 条款49: 学会破解STL相关的编译器出错信息 条款50: 让自己熟悉STL相关的网站
》灰《《常好的STL教程Effective STL 目录 容器 条款1: 仔细选择你要的容器 条款2: 小心对“容器无关代码”的幻想 条款3: 使容器里对象的拷贝操作轻量而正确 条款4: 用empty来代替检查size是否为0 条款5: 尽量使用范围成员函数代替他们的单元素兄弟 条款6: 警惕C++的及其令人恼怒的分析 条款7: 当使用new得指针的容器时,切记在容器销毁前delete那些指针 条款8: 千万不要把auto_ptr放入容器 条款9: 小心选择删除选项 条款10: 当心allocator的协定和约束 条款11: 了解自定义allocator的正统使用法 条款12: 对STL容器的线程安全性的期待现实一些 vector和string 条款13: 尽量使用vector和string来代替动态申请的数组 条款14: 用reserve来避免不必要的内存重新分配 条款15: 当心string的实现的变化 条款16: 如何将vector和string的数据传给传统的API 条款17: 用“交换技巧”来修正过度的容量 条款18: 避免使用vector 关联容器 条款19: 了解相等和等价的区别 条款20: 为包含指针的关联容器指定比较类型 条款21: 永远让比较函数对相等的值返回false 条款22: 避免对set和multiset的键值进行修改 条款23: 考虑用排序的vector代替关联容器 条款24: 当效率很关键时尽量用map::insert代替map::operator 条款25: 让自己熟悉非标准的hash容器 迭代器 条款26: 尽量使用iterator代替const_iterator,reverse_iterator和const_reverse_iterator 条款27: 使用distance和advance把const_iterators转化成iterators 条款28: 了解如何通过reverse_iterator的base得到iterator 条款29: 需要一字符一字符输入时请用istreambuf_iterator 算法 条款30: 确保目的范围足够大 条款31: 了解你的排序选项 条款32: 如果你真的想删除东西的话在remove-like的算法后紧接上erase 条款33: 当心在包含指针的容器使用remove-like的算法 条款34: 注意哪些算法需要排序过的范围 条款35: 通过mismatch或lexicographical_compare实现简单的忽略大小写字符串比较 条款36: 用not1和remove_copy_if来表现copy_if 条款37: 用accumulate或for_each来统计序列 仿函数,仿函数类,函数等等 条款38: 把仿函数类设计成值传递的 条款39: 用纯函数做predicate 条款40: 增强仿函数类的适应性 条款41: 明确ptr_fun, mem_fun和mem_fun_ref的区别 条款42: 保证less是operator<的意思 用STL编程 条款43: 尽量用算法调用代替手写循环 条款44: 尽量用成员函数代替同名的算法 条款45: 注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46: 考虑用函数对象代替函数作为算法的参数 条款47: 避免产生只写代码 条款48: 总是#include适当的头文件 条款49: 学会破解STL相关的编译器出错信息 条款50: 让自己熟悉STL相关的网站
条款1:仔细选择你的容器 条款2:小心对“容器无关代码”的幻想 条款3:使容器里对象的拷贝操作轻量而正确 条款4:用empty来代替检查size()是否为0 条款5:尽量使用区间成员函数代替它们的单元素兄弟" 条款6:警惕C++最令人恼怒的解析 条款7:当使用new得指针的容器时,记得在销毁容器前delete那些指针 条款8:永不建立auto_ptr的容器 条款9:在删除选项仔细选择 条款10:注意分配器的协定和约束 条款11:理解自定义分配器的正确用法 条款12:对STL容器线程安全性的期待现实一些 vector和string 条款13:尽量使用vector和string来代替动态分配的数组 条款14:使用reserve来避免不必要的重新分配 条款15:小心string实现的多样性 条款16:如何将vector和string的数据传给传统的API 条款17:使用“交换技巧”来修整过剩容量 条款18:避免使用vector 关联容器 条款19:了解相等和等价的区别 条款20:为指针的关联容器指定比较类型 条款21:永远让比较函数对相等的值返回false 条款22:避免原地修改set和multiset的键 条款23:考虑使用有序vector代替关联容器 条款24:当关乎效率时应该在map::operator[]和map-insert之间仔细选择 条款25:熟悉非标准散列容器 迭代器 条款26:尽量用iterator代替const_iterator,reverse_iterator和const_reverse_iterator 条款27:用distance和advance把const_iterator转化成iterator 条款28:了解如何通过reverse_iterator的base得到iterator 条款29:需要一个一个字符输入时考虑使用istreambuf_iterator 算法 条款30:确保目标区间足够大 条款31:了解你的排序选择 条款32:如果你真的想删除东西的话就在类似remove的算法后接上erase 条款33:提防在指针的容器上使用类似remove的算法 条款34:注意哪个算法需要有序区间 条款35:通过mismatch或lexicographical比较实现简单的忽略大小写字符串比较 条款36:了解copy_if的正确实现 条款37:用accumulate或for_each来统计区间 仿函数、仿函数类、函数等 条款38:把仿函数类设计为用于值传递 条款39:用纯函数做判断式 条款40:使仿函数类可适配 条款41:了解使用ptr_fun、mem_fun和mem_fun_ref的原因 条款42:确定less表示operator< 使用STL编程 条款43:尽量用算法调用代替手写循环 条款44:尽量用成员函数代替同名的算法 条款45:注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46:考虑使用函数对象代替函数作算法的参数 条款47:避免产生只写代码 条款48:总是#include适当的头文件 条款49:学习破解有关STL的编译器诊断信息 条款50:让你自己熟悉有关STL的网站 参考书目 附录A:区域设置和忽略大小写的字符串比较 附录B:在微软STL平台上的注意事项 词汇表 索引
不知道网上有没有Effective STL(文),我找不到,我自己整理出了这个《Effective STL(文)》共享给需要的人。

《Effective STL》目录:

前言
致谢
导读
容器
条款1:仔细选择你的容器
条款2:小心对“容器无关代码”的幻想
条款3:使容器里对象的拷贝操作轻量而正确
条款4:用empty来代替检查size()是否为0
条款5:尽量使用区间成员函数代替它们的单元素兄弟
条款6:警惕C++最令人恼怒的解析
条款7:当使用new得指针的容器时,记得在销毁容器前delete那些指针
条款8:永不建立auto_ptr的容器
条款9:在删除选项仔细选择
条款10:注意分配器的协定和约束
条款11:理解自定义分配器的正确用法
条款12:对STL容器线程安全性的期待现实一些
vector和string
条款13:尽量使用vector和string来代替动态分配的数组
条款14:使用reserve来避免不必要的重新分配
条款15:小心string实现的多样性
条款16:如何将vector和string的数据传给传统的API
条款17:使用“交换技巧”来修整过剩容量
条款18:避免使用vector
关联容器
条款19:了解相等和等价的区别
条款20:为指针的关联容器指定比较类型
条款21:永远让比较函数对相等的值返回false
条款22:避免原地修改set和multiset的键
条款23:考虑使用有序vector代替关联容器
条款24:当关乎效率时应该在map::operator[]和map-insert之间仔细选择
条款25:熟悉非标准散列容器
迭代器
条款26:尽量用iterator代替const_iterator,reverse_iterator和const_reverse_iterator
条款27:用distance和advance把const_iterator转化成iterator
条款28:了解如何通过reverse_iterator的base得到iterator
条款29:需要一个一个字符输入时考虑使用istreambuf_iterator
算法
条款30:确保目标区间足够大
条款31:了解你的排序选择
条款32:如果你真的想删除东西的话就在类似remove的算法后接上erase
条款33:提防在指针的容器上使用类似remove的算法
条款34:注意哪个算法需要有序区间
条款35:通过mismatch或lexicographical比较实现简单的忽略大小写字符串比较
条款36:了解copy_if的正确实现
条款37:用accumulate或for_each来统计区间
仿函数、仿函数类、函数等
条款38:把仿函数类设计为用于值传递
条款39:用纯函数做判断式
条款40:使仿函数类可适配
条款41:了解使用ptr_fun、mem_fun和mem_fun_ref的原因
条款42:确定less表示operator<.
使用STL编程
条款43:尽量用算法调用代替手写循环
条款44:尽量用成员函数代替同名的算法
条款45:注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别
条款46:考虑使用函数对象代替函数作算法的参数
条款47:避免产生只写代码
条款48:总是#include适当的头文件
条款49:学习破解有关STL的编译器诊断信息
条款50:让你自己熟悉有关STL的网站
参考书目
附录A:区域设置和忽略大小写的字符串比较
附录B:在微软STL平台上的注意事项
词汇表
索引
关于本电子书

64,281

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧