问题

最近在写 AVL 树的问题,其中涉及到大量的指针操作。但由于出现了 bug ,在没有修复时出现了单步调试和直接编译运行的结果不一样的情况。大致情况是:单步调试能够根据逻辑把结果运行出来,但是编译运行会出现程序异常中断的情况

问题代码

#include<iostream>
#include <cmath>
using namespace std;template<class K,class V>
struct AVLTreeNode{AVLTreeNode<K, V>* _left;AVLTreeNode<K, V>* _right;AVLTreeNode<K, V>* _parent;K _key;V _value;int  _bf;   //平衡因子AVLTreeNode(const K& key,const V& value):_key(key), _value(value), _left(NULL), _right(NULL), _parent(NULL), _bf(0){}
};template<class K,class V>
class AVLTree{typedef AVLTreeNode<K, V> Node;
public:AVLTree():_root(NULL){}bool Insert(const K& key, const V& value){if (_root == NULL){_root = new Node(key,value);return true;}Node* cur = _root;Node* parent = NULL;while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else{return false;}}cur = new Node(key,value);if (parent->_key > key){parent->_left = cur;cur->_parent = parent;}else{parent->_right = cur;cur->_parent = parent;}//更新平衡因子//不平衡,则进行旋转while (parent){if (parent->_right==cur)parent->_bf++;elseparent->_bf--;//父节点平衡因子为0时,退出(说明父节点的两边高度一样,算路径长度的话都一样,没有影响)if (parent->_bf == 0)break;//父节点平衡因子为1或-1的时候(说明是从0+1或0-1得来的),父节点两边高度不同,故需要继续更新平衡因子else if (parent->_bf == 1 || parent->_bf == -1){cur = parent;parent = cur->_parent;}//父节点平衡因子为2或-2时,旋转else  //(parent->_bf==2||parent->_bf==-2) 旋转{if (parent->_bf == -2){if (cur->_bf == -1)//右单旋{_RotateR(parent);}else //(cur->_bf==1) 左右单旋{_RotateLR(parent);}}else //(parent->_bf==2){if (cur->_bf == 1)  //左单旋{_RotateL(parent);}else  //(cur->_bf==-1)右左单旋{_RotateRL(parent);}}break;}}}Node* Find(const K& key){if (_root == NULL)return NULL;Node* cur = _root;while (cur){if (cur->_key > key)cur = cur->_left;else if (cur->_key < key)cur = cur->_right;elsereturn cur;}return NULL;}bool Remove(const K& key){if (_root == NULL)return false;Node* parent = NULL;Node* cur = _root;while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else{Node* del;if (cur->_right == NULL){del = cur;if (parent == NULL){_root = cur->_left;//_root->_bf = 0;}else{if (parent->_left == cur){parent->_left = cur->_left;parent->_bf++;}else{parent->_right = cur->_left;parent->_bf--;}}delete del;}else if (cur->_left == NULL){del = cur;if (parent == NULL){_root = cur->_right;_root->_bf = 0;cout << "cur : " << cur->_key << endl;}else{if (parent->_left == cur){parent->_left = cur->_right;parent->_bf++;}else{parent->_right = cur->_right;parent->_bf--;}}delete del;}else{parent = cur;Node* left = cur->_right;while (left->_left){parent = left;left = left->_left;}del = left;cur->_key = left->_key;cur->_value = left->_value;if (parent->_left == left){parent->_left = left->_right;parent->_bf++;}else{parent->_right = left->_right;parent->_bf--;}delete del;}break;}}if (cur == NULL){return false;}while (parent){if (parent->_bf == 0){break;}else if (parent->_bf == 1 || parent->_bf == -1){break;}else //parent->_bf=2||parent->_bf=-2{if (parent->_bf == -2){if (cur->_bf == -1)_RotateR(parent);else  //cur->_bf=1_RotateLR(parent);}else{if (cur->_bf == 1)_RotateL(parent);else_RotateRL(parent);}break;}}return true;}void InOrder(){_InOrder(_root);cout << endl;}//判断这棵树是否是平衡搜索树bool IsBlance(){return _IsBlance(_root);}
protected:void _RotateR(Node* parent){Node* subL = parent->_left;Node* subLR=subL->_right;parent->_left = subLR;if (subLR != NULL){subLR->_parent = parent;}subL->_right = parent;Node* ppNode = parent->_parent;parent->_parent = subL;if (ppNode == NULL){_root = subL;subL->_parent = NULL;}else{if (ppNode->_left == parent){ppNode->_left = subL;subL->_parent = ppNode;}else{ppNode->_right = subL;subL->_parent = ppNode;}}subL->_bf = parent->_bf = 0;}void _RotateL(Node* parent){Node* subR = parent->_right;Node* subRL= subR->_left;parent->_right = subRL;if (subRL != NULL){subRL->_parent = parent;}subR->_left = parent;Node* ppNode = parent->_parent;parent->_parent = subR;if (ppNode == NULL){_root = subR;subR->_parent = NULL;}else{if (ppNode->_left == parent){ppNode->_left = subR;subR->_parent = ppNode;}else{ppNode->_right = subR;subR->_parent = ppNode;}}subR->_bf = parent->_bf = 0;}void _RotateRL(Node* parent){Node* subR = parent->_right;Node* subRL= subR->_left;int bf = subRL->_bf;_RotateR(parent->_right);_RotateL(parent);if (bf == 1) //从subRL的右边插入{parent->_bf = -1;subR->_bf = 0;}else if (bf == -1) //从subRL的左边插入{parent->_bf = 0;subR->_bf = 1;}else    //(bf=0){parent->_bf = 0;subR->_bf = 0;}subRL->_bf = 0;}void _RotateLR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;int bf = subLR->_bf;_RotateL(parent->_left);_RotateR(parent);if (bf == 1){parent->_bf = 0;subL->_bf = -1;}else if (bf == -1){parent->_bf = 1;subL->_bf = 0;}else   //bf=0{parent->_bf = 0;subL->_bf = 0;}subLR->_bf = 0;}bool _IsBlance(Node* root){if (root == NULL)return true;int right = _Height(root->_right);int left = _Height(root->_left);if (right - left != root->_bf || abs(right - left) >= 2){cout << "平衡因子异常" << root->_key << endl;return false;}return _IsBlance(root->_left) && _IsBlance(root->_right);}int _Height(Node* root){if (root == NULL)return 0;int right = _Height(root->_right);int left = _Height(root->_left);if (right > left)return (right + 1);elsereturn (left + 1);}void _InOrder(Node* root){if (root == NULL){return;}else{_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}}
protected:Node* _root;
};void Test1()
{cout << "Test1 : " << endl;int a[9] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };AVLTree<int, int> avl;for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i){avl.Insert(a[i],i);}avl.InOrder();cout<<avl.IsBlance()<<endl;AVLTreeNode<int, int>* ret1 = avl.Find(18);if (ret1)cout << ret1->_key << ":" << ret1->_value << endl;elsecout << "不存在ret1" << endl;AVLTreeNode<int, int>* ret2 = avl.Find(1);if (ret2)cout << ret2->_key << ":" << ret2->_value << endl;elsecout << "不存在ret2" << endl;avl.Remove(26);avl.Remove(18);avl.Remove(15);avl.InOrder();avl.Remove(3);cout << avl.Remove(7) << endl;cout << avl.Remove(7) << endl;cout << avl.Remove(9) << endl;cout << avl.Remove(11) << endl;avl.InOrder();cout << avl.IsBlance() << endl;avl.InOrder();cout << avl.Remove(14) << endl;cout << avl.Remove(15) << endl;avl.Remove(9);avl.Remove(11);avl.Remove(14);avl.Remove(15);cout << avl.Remove(100) << endl;avl.Remove(16);avl.Remove(18);avl.Remove(26);avl.InOrder();
}void Test2()
{cout << "Test2 : " << endl;int a[10] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };AVLTree<int, int> avl;for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i){avl.Insert(a[i], i);}avl.InOrder();cout << avl.IsBlance() << endl;AVLTreeNode<int, int>* ret1 = avl.Find(5);if (ret1)cout << ret1->_key << ":" << ret1->_value << endl;elsecout << "不存在ret1" << endl;AVLTreeNode<int, int>* ret2 = avl.Find(88);if (ret2)cout << ret2->_key << ":" << ret2->_value << endl;elsecout << "不存在ret2" << endl;avl.Remove(14);avl.Remove(16);avl.Remove(7);avl.InOrder();avl.Remove(15);avl.Remove(6);avl.Remove(5);cout << avl.Remove(4) << endl;avl.Remove(4);avl.Remove(3);avl.Remove(2);avl.Remove(1);cout << avl.Remove(100) << endl;avl.Remove(7);avl.Remove(16);avl.InOrder();
}int main()
{Test1();cout << endl;cout << endl;Test2();return 0;
}

分析

问题中阐述的两种运行方式分别对应着 debug 和 release 版本的结果,区别在于 release 版本会进行一定的编译优化。

说点题外话,我们再来回顾一个 C/C++ 程序从 .c 文件到 .exe的可执行文件的流程:

#mermaid-svg-jdhsqn0BbFyef4hw .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-jdhsqn0BbFyef4hw .label text{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw .node rect,#mermaid-svg-jdhsqn0BbFyef4hw .node circle,#mermaid-svg-jdhsqn0BbFyef4hw .node ellipse,#mermaid-svg-jdhsqn0BbFyef4hw .node polygon,#mermaid-svg-jdhsqn0BbFyef4hw .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-jdhsqn0BbFyef4hw .node .label{text-align:center;fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw .node.clickable{cursor:pointer}#mermaid-svg-jdhsqn0BbFyef4hw .arrowheadPath{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-jdhsqn0BbFyef4hw .flowchart-link{stroke:#333;fill:none}#mermaid-svg-jdhsqn0BbFyef4hw .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-jdhsqn0BbFyef4hw .edgeLabel rect{opacity:0.9}#mermaid-svg-jdhsqn0BbFyef4hw .edgeLabel span{color:#333}#mermaid-svg-jdhsqn0BbFyef4hw .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-jdhsqn0BbFyef4hw .cluster text{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-jdhsqn0BbFyef4hw .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-jdhsqn0BbFyef4hw text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-jdhsqn0BbFyef4hw .actor-line{stroke:grey}#mermaid-svg-jdhsqn0BbFyef4hw .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-jdhsqn0BbFyef4hw .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-jdhsqn0BbFyef4hw #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-jdhsqn0BbFyef4hw .sequenceNumber{fill:#fff}#mermaid-svg-jdhsqn0BbFyef4hw #sequencenumber{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw #crosshead path{fill:#333;stroke:#333}#mermaid-svg-jdhsqn0BbFyef4hw .messageText{fill:#333;stroke:#333}#mermaid-svg-jdhsqn0BbFyef4hw .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-jdhsqn0BbFyef4hw .labelText,#mermaid-svg-jdhsqn0BbFyef4hw .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-jdhsqn0BbFyef4hw .loopText,#mermaid-svg-jdhsqn0BbFyef4hw .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-jdhsqn0BbFyef4hw .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-jdhsqn0BbFyef4hw .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-jdhsqn0BbFyef4hw .noteText,#mermaid-svg-jdhsqn0BbFyef4hw .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-jdhsqn0BbFyef4hw .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-jdhsqn0BbFyef4hw .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-jdhsqn0BbFyef4hw .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-jdhsqn0BbFyef4hw .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw .section{stroke:none;opacity:0.2}#mermaid-svg-jdhsqn0BbFyef4hw .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-jdhsqn0BbFyef4hw .section2{fill:#fff400}#mermaid-svg-jdhsqn0BbFyef4hw .section1,#mermaid-svg-jdhsqn0BbFyef4hw .section3{fill:#fff;opacity:0.2}#mermaid-svg-jdhsqn0BbFyef4hw .sectionTitle0{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw .sectionTitle1{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw .sectionTitle2{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw .sectionTitle3{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-jdhsqn0BbFyef4hw .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw .grid path{stroke-width:0}#mermaid-svg-jdhsqn0BbFyef4hw .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-jdhsqn0BbFyef4hw .task{stroke-width:2}#mermaid-svg-jdhsqn0BbFyef4hw .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw .taskText:not([font-size]){font-size:11px}#mermaid-svg-jdhsqn0BbFyef4hw .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-jdhsqn0BbFyef4hw .task.clickable{cursor:pointer}#mermaid-svg-jdhsqn0BbFyef4hw .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-jdhsqn0BbFyef4hw .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-jdhsqn0BbFyef4hw .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-jdhsqn0BbFyef4hw .taskText0,#mermaid-svg-jdhsqn0BbFyef4hw .taskText1,#mermaid-svg-jdhsqn0BbFyef4hw .taskText2,#mermaid-svg-jdhsqn0BbFyef4hw .taskText3{fill:#fff}#mermaid-svg-jdhsqn0BbFyef4hw .task0,#mermaid-svg-jdhsqn0BbFyef4hw .task1,#mermaid-svg-jdhsqn0BbFyef4hw .task2,#mermaid-svg-jdhsqn0BbFyef4hw .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-jdhsqn0BbFyef4hw .taskTextOutside0,#mermaid-svg-jdhsqn0BbFyef4hw .taskTextOutside2{fill:#000}#mermaid-svg-jdhsqn0BbFyef4hw .taskTextOutside1,#mermaid-svg-jdhsqn0BbFyef4hw .taskTextOutside3{fill:#000}#mermaid-svg-jdhsqn0BbFyef4hw .active0,#mermaid-svg-jdhsqn0BbFyef4hw .active1,#mermaid-svg-jdhsqn0BbFyef4hw .active2,#mermaid-svg-jdhsqn0BbFyef4hw .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-jdhsqn0BbFyef4hw .activeText0,#mermaid-svg-jdhsqn0BbFyef4hw .activeText1,#mermaid-svg-jdhsqn0BbFyef4hw .activeText2,#mermaid-svg-jdhsqn0BbFyef4hw .activeText3{fill:#000 !important}#mermaid-svg-jdhsqn0BbFyef4hw .done0,#mermaid-svg-jdhsqn0BbFyef4hw .done1,#mermaid-svg-jdhsqn0BbFyef4hw .done2,#mermaid-svg-jdhsqn0BbFyef4hw .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-jdhsqn0BbFyef4hw .doneText0,#mermaid-svg-jdhsqn0BbFyef4hw .doneText1,#mermaid-svg-jdhsqn0BbFyef4hw .doneText2,#mermaid-svg-jdhsqn0BbFyef4hw .doneText3{fill:#000 !important}#mermaid-svg-jdhsqn0BbFyef4hw .crit0,#mermaid-svg-jdhsqn0BbFyef4hw .crit1,#mermaid-svg-jdhsqn0BbFyef4hw .crit2,#mermaid-svg-jdhsqn0BbFyef4hw .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-jdhsqn0BbFyef4hw .activeCrit0,#mermaid-svg-jdhsqn0BbFyef4hw .activeCrit1,#mermaid-svg-jdhsqn0BbFyef4hw .activeCrit2,#mermaid-svg-jdhsqn0BbFyef4hw .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-jdhsqn0BbFyef4hw .doneCrit0,#mermaid-svg-jdhsqn0BbFyef4hw .doneCrit1,#mermaid-svg-jdhsqn0BbFyef4hw .doneCrit2,#mermaid-svg-jdhsqn0BbFyef4hw .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-jdhsqn0BbFyef4hw .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-jdhsqn0BbFyef4hw .milestoneText{font-style:italic}#mermaid-svg-jdhsqn0BbFyef4hw .doneCritText0,#mermaid-svg-jdhsqn0BbFyef4hw .doneCritText1,#mermaid-svg-jdhsqn0BbFyef4hw .doneCritText2,#mermaid-svg-jdhsqn0BbFyef4hw .doneCritText3{fill:#000 !important}#mermaid-svg-jdhsqn0BbFyef4hw .activeCritText0,#mermaid-svg-jdhsqn0BbFyef4hw .activeCritText1,#mermaid-svg-jdhsqn0BbFyef4hw .activeCritText2,#mermaid-svg-jdhsqn0BbFyef4hw .activeCritText3{fill:#000 !important}#mermaid-svg-jdhsqn0BbFyef4hw .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-jdhsqn0BbFyef4hw g.classGroup text .title{font-weight:bolder}#mermaid-svg-jdhsqn0BbFyef4hw g.clickable{cursor:pointer}#mermaid-svg-jdhsqn0BbFyef4hw g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-jdhsqn0BbFyef4hw g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-jdhsqn0BbFyef4hw .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-jdhsqn0BbFyef4hw .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-jdhsqn0BbFyef4hw .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-jdhsqn0BbFyef4hw .dashed-line{stroke-dasharray:3}#mermaid-svg-jdhsqn0BbFyef4hw #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-jdhsqn0BbFyef4hw #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-jdhsqn0BbFyef4hw #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-jdhsqn0BbFyef4hw #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-jdhsqn0BbFyef4hw #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-jdhsqn0BbFyef4hw #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-jdhsqn0BbFyef4hw #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-jdhsqn0BbFyef4hw #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-jdhsqn0BbFyef4hw .commit-id,#mermaid-svg-jdhsqn0BbFyef4hw .commit-msg,#mermaid-svg-jdhsqn0BbFyef4hw .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-jdhsqn0BbFyef4hw g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-jdhsqn0BbFyef4hw g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-jdhsqn0BbFyef4hw g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-jdhsqn0BbFyef4hw .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-jdhsqn0BbFyef4hw .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-jdhsqn0BbFyef4hw .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-jdhsqn0BbFyef4hw .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-jdhsqn0BbFyef4hw .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-jdhsqn0BbFyef4hw .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-jdhsqn0BbFyef4hw .edgeLabel text{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-jdhsqn0BbFyef4hw .node circle.state-start{fill:black;stroke:black}#mermaid-svg-jdhsqn0BbFyef4hw .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-jdhsqn0BbFyef4hw #statediagram-barbEnd{fill:#9370db}#mermaid-svg-jdhsqn0BbFyef4hw .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-jdhsqn0BbFyef4hw .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-jdhsqn0BbFyef4hw .statediagram-state .divider{stroke:#9370db}#mermaid-svg-jdhsqn0BbFyef4hw .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-jdhsqn0BbFyef4hw .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-jdhsqn0BbFyef4hw .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-jdhsqn0BbFyef4hw .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-jdhsqn0BbFyef4hw .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-jdhsqn0BbFyef4hw .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-jdhsqn0BbFyef4hw .note-edge{stroke-dasharray:5}#mermaid-svg-jdhsqn0BbFyef4hw .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-jdhsqn0BbFyef4hw .error-icon{fill:#522}#mermaid-svg-jdhsqn0BbFyef4hw .error-text{fill:#522;stroke:#522}#mermaid-svg-jdhsqn0BbFyef4hw .edge-thickness-normal{stroke-width:2px}#mermaid-svg-jdhsqn0BbFyef4hw .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-jdhsqn0BbFyef4hw .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-jdhsqn0BbFyef4hw .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-jdhsqn0BbFyef4hw .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-jdhsqn0BbFyef4hw .marker{fill:#333}#mermaid-svg-jdhsqn0BbFyef4hw .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;} #mermaid-svg-jdhsqn0BbFyef4hw {color: rgba(0, 0, 0, 0.75);font: ;}

预处理,把宏替换
编译,转成汇编代码
汇编,转成二进制代码
链接,生成可执行文件
.c 文件
.i 文件
.s 文件
.o 文件
.exe 文件

其中,编译优化就是在汇编代码中优化一些不必要的操作。例如本代码的问题是出现了访问到已经被 delete 的内存,对于 debug 版本,在访问内存的指针中会通过 ebp 寄存器,而这种方式会允许少量数组越界或者访问非法内存的情况,进而能让程序继续运行;而对于 release 却会优化会省略 ebp 栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃,这种指针又称 帧指针

解决

问题的关键是程序中,被删除的子节点的孩子节点的父亲指针没有正确设置,以及删除后其祖先节点的平衡因子没有调整导致,所修改 Remove 部分代码即可。

参考

  1. C++ debug和release版本的区别及调试技巧
  2. esp和ebp详解

C++ debug和release版本运行结果不一致浅析相关推荐

  1. Qt debug版本运行正常release版本运行崩溃问题记录

    问题由来 某一项目debug版本运行正常,进入发布阶段,结果release后的版本出现了崩溃问题,因为是release版本,不能debug运行,只能通过printf debug,虽然问题原因很简单,但 ...

  2. VS Debug和Release版本的区别

    VS Debug和Release版本的区别 1. 变量. 大家都知道,debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc(注1),而release的赋值 ...

  3. VC中debug和release版本的区别

    vc中debug和release的不同 收藏  在使用VC开发软件的过程中,正当要享受那种兴奋的时候突然发现:release与debug运行结果不一致,甚至出错,而release又不方便调试,真的是当 ...

  4. Debug和release版本区别 原码反码补码的转换及存储

    #define _CRT_SECURE_NO_WARNINGS 1  //Debug和release版本区别(VS2019版) //例子 #include<stdio.h> //int m ...

  5. 嵌入式开发 | 软件项目中 Debug 和 Release 版本的差异

    关注+星标公众号,不错过精彩内容 作者 | strongerHuang 微信公众号 | strongerHuang 很多集成开发环境(IDE),比如VS(VC).IAR等,在创建工程时都会自动生成有D ...

  6. 软件项目中Debug 和 Release版本差异

    关注+星标公众号,不错过精彩内容 作者 | strongerHuang 微信公众号 | 嵌入式专栏 有很多软件集成开发环境(IDE),比如VS(VC).IAR等,在创建工程时都会自动生成有Debug ...

  7. VS中Debug和Release版本的区别

    之前写过一段代码,能在VS2013的Release下运行,但是不能在Debug下运行,所以又深入学习了一番,下面是学到的经验.(橙色表示引用,红色表示重点) VS中的程序有Debug和Release两 ...

  8. Debug与Release版本的区别

    由于最近搞了个项目,在Dedug版本下正常,但Release版本就有问题,看样子还是debug版本和release版本的区别没有搞清楚. 有遇到下面3个问题: 1.Debug版本下程序可以正常运行退出 ...

  9. C++ debug和release版本的区别及调试技巧

    一.Debug 和 Release 编译方式的本质区别 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使得程 ...

最新文章

  1. 手机怎样投屏到电脑_手机有线投屏到Windows电脑
  2. ROR与社区网站开发
  3. 配置文件~/.ssh/config和/etc/ssh/ssh_config
  4. OCM_第十九天课程:Section9 —》Data Guard _ DATA GUARD 原理/DATA GUARD 应用/DATA GUARD 搭建...
  5. overline css,CSS text-decoration-line 属性
  6. 技术实践丨手把手教你使用MQTT方式对接华为IoT平台
  7. (5)verilog语言编写呼吸灯
  8. JAVA面试要点004_JAVA编程过程中为了性能优化_应该注意到的地方
  9. 【李宏毅2020 ML/DL】P3 Regression - Case Study
  10. webStrom 开始你的第一个React应用
  11. python游戏程序中游戏对象是什么_Python游戏编程入门
  12. MISC图片隐写之foremost
  13. 要闻君说:小米手机部组织架构突现大调整;河南联通重启VDC扩容工程招标;英特尔已收购Ineda Systems,剑指独显;...
  14. 北航计算机本科生考研,和计算机考研的师弟师妹们分享一下经验本人本科北航...
  15. 微博运营的5个经典案例
  16. warpaffine 旋转有一部分消失_OpenCV warpAffine的天坑
  17. CocosCreator之Tween缓动动画
  18. [spring源码学习]六、IOC源码-BeanFactory和factory-bean
  19. 十大免费教程资源帮助新手快速学习JavaScript
  20. linux 不同用户时间,Linux时间子系统之(一):时间的基本概念

热门文章

  1. shell数值计算(加减乘除)
  2. node.js及vue下使用chosen插件
  3. 思科路由器高危漏洞可导致攻击者完全访问小企业网络
  4. app保险箱,保险箱登录注册,添加保险箱子,实现对保险箱的监听。
  5. 二元随机变量,分布律,联合分布函数
  6. selenium无头浏览爬取搜狐新闻
  7. Kaggle练习赛Spaceship Tantic 数据探索(下)规律一致性分析与对抗性验证
  8. 第9届蓝桥杯 国赛 java C组
  9. windows的磁盘操作之二——初始化磁盘
  10. 金三银四软件测试工程师面试题(含答案)