vector 出错 vector iterators incompatible
本帖最后由 zy8818 于 2021-11-13 13:47 编辑vector 出错
编译器提示
Expression:vector iterators incompatible
定义:
//多叉树结构
struct TreeNode
{
CPoint pos; //当前点
vector<TreeNode*> childs;//子节点动态数组
TreeNode* pParent;//父节点
};
源码:
vector<TreeNode*>::iterator it;
TreeNode* pNew = new TreeNode;
memset(pNew, 0, sizeof TreeNode);//把此行注释后while (it != pRoot->childs.end())可以用 但是链表的父节点不为空就做不了根节点,父节点循环失效
//起点为根节点
TreeNode* pRoot = pNew;
//buff动态数组
vector<TreeNode*>buff;
//当前节点
TreeNode* pCurrent = pRoot;
TreeNode* pChild2 = new TreeNode;
memset(pChild2, 0, sizeof TreeNode);
TreeNode *pTemp = new TreeNode;
memset(pTemp, 0, sizeof TreeNode);
//加入pRoot成员childs vector
pCurrent->childs.push_back(pChild2);
pCurrent->childs.push_back(pTemp);
//父节点指向pRoot
pChild2->pParent = pRoot;
pTemp->pParent = pRoot;
//入buff vector
buff.push_back(pChild2);
buff.push_back(pTemp);
it = pRoot->childs.begin();
while (it != pRoot->childs.end())//出错断在此行
{
it++;
AfxMessageBox(TEXT("|"));
}
it = buff.begin();
while (it != buff.end())//下面的循环没有任何问题
{
it++;
AfxMessageBox(TEXT("|"));
} 好家伙,memset(pNew, 0, sizeof(TreeNode))直接把vector的内存置零了,不出bug才怪
直接pNew->pParent = 0;就行了 本帖最后由 zy8818 于 2021-11-13 19:59 编辑
lhgzbxhz 发表于 2021-11-13 19:27
好家伙,memset(pNew, 0, sizeof(TreeNode))直接把vector的内存置零了,不出bug才怪
直接pNew->pParent =...
什么原理?我用debung调试模式看注释和不注释memset的情况下 pRoot->childs下面都有两个push进去的对象
pNew->pParent = 0我也跟着学习一下 混点鱼币{:10_257:} 本帖最后由 zy8818 于 2021-11-14 10:17 编辑
zhsguitar 发表于 2021-11-13 22:09
pNew->pParent = 0我也跟着学习一下 混点鱼币
真正的原理没有找到兄弟们,单条指令pNew->pParent = 0我也会,不然我怎么知道注释memset,我想知道的是后面的原理,
为什么memset写NULL值之后debug还可以看到 pRoot->childs里面有两个push进去的点,按照这个道理如果是清空childs.vector内存写了NULL值肯定push的时候就会debug断下出错
就好像你创建一个指针然后指向new一个空间,我突然把指针指向NULL,然后你在*p=写值进去肯定会出错 解决方案不是重要的,我是想知道其中的工作原理,这样以后用起来才会得心应手,不然总感觉没有搞懂 zy8818 发表于 2021-11-13 19:45
什么原理?我用debung调试模式看注释和不注释memset的情况下 pRoot->childs下面都有两个push进去的对象 ...
这个原理很复杂(我dubug了半天也没搞清楚),但你不需要知道
原因很简单:原理不具有可移植性。
具体点说,对vector这种不具有内存平凡型的类使用memset()这类字节操作是未定义行为,这之后的一切行为都由编译器实现决定。我用Mingw测试的时候push_back()没有问题,用iterator遍历也没有问题。但用VS2019测试时push_back()没有问题,用iterator遍历出了问题。
写C++一定要牢记一个原则:永远不要尝试未定义行为,更不要尝试探究未定义行为背后的原理,因为换一个编译器(甚至是升级一个版本),其原理就会发生改变。知道其中的工作原理不仅不会让你用起来得心应手,还会让你撞得头破血流。请相信我学C++这几年的经验下次离未定义行为越远越好 lhgzbxhz 发表于 2021-11-14 19:13
这个原理很复杂(我dubug了半天也没搞清楚),但你不需要知道
原因很简单:原理不具有可移植性。
具体 ...
我明白了,你的意思是说不能把c语言那种赤裸裸可以自己完全把控的结构来用到高级语言c++的结构中来,
如果是纯c,纯自己结构体用memset就不会有问题
说白了用别人的高级语言就的遵守他的规则,所以memset只实用与c 兄弟你讲的太对了,编译器的工作原理事情,只能让编译器去头痛,如果出bug肯定是自己的原因,原因就是不符合编程语言的规则
只要明白这个道理,谁的语言规则谁做主,遵守他的规则就行 memset只适合用在普通变量类型上面(例如int ,char[],int[],……等等)就是高级语言也是没有问题的,所以大家谨慎使用memset格式化高级语言的结构体或者高级类型,没准哪天bug就出来了,而且还不知道是哪里出问题了
页:
[1]