问题
I have a question about parsing the string s into a binary tree.
struct TreeNode {
string val; // The data in this node.
TreeNode *left; // Pointer to the left subtree.
TreeNode *right; // Pointer to the right subtree.
};
string s="((OR (AND pass (NOT reject)) (AND (NOT pass) reject)))";
I do some stroke and eliminate the "(" and ")" and keep all the separate part in vector aftersplit, aftersplit has (bottom) OR AND pass NOT reject AND NOT pass reject (back)
vector<string> aftersplit;
vector<TreeNode> parsetree;
while (!aftersplit.empty())//do the parsing
{
TreeNode *temp=new TreeNode;
temp->val=aftersplit.back();
temp->left=NULL;
temp->right=NULL;
aftersplit.pop_back();
if(temp->val=="AND"||temp->val=="OR"||temp->val=="=>"||temp->val=="<=>"){
TreeNode *leftnode = new TreeNode;
leftnode=&parsetree.back();
parsetree.pop_back();
temp->left=leftnode;
TreeNode *rightnode = new TreeNode;
rightnode=&parsetree.back();
parsetree.pop_back();
temp->right=rightnode;
parsetree.push_back(temp); //can not put the temp into parsetree
}
else if(temp->val=="NOT")
{
TreeNode *leftnode = new TreeNode;
leftnode=&parsetree.back();
parsetree.pop_back();
temp->left=leftnode;
parsetree.push_back(temp);
}
else {
parsetree.push_back(temp);
}
}
I deal with string s from right to left
however when I run "TreeNode leftnode" when operator is "OR"; the lefenode was allocated an address which is using by first "AND"'s left child "pass", that is to say, the "AND"'s point to his left children at address 0x00007fff6d8da7e0, and the new temporary leftnode's is allocating address 0x00007fff6d8da7e0 too after that before that the tree is like
(AND) / \ / \ pass (NOT) / reject
after that leftnode is allocated the address of "pass" it will like
(AND) / \ / \ (AND) (NOT) / \ / / \ / (AND) (NOT) reject / \ / \ (AND) (NOT)
and etc, all point to itself, I know there maybe something wrong with pointer, but I can not figure out. please help me
回答1:
if(temp.val=="AND"||temp.val=="OR"||temp.val=="=>"||temp.val=="<=>"){
TreeNode leftnode; //appear a bug here
leftnode=parsetree.back();
parsetree.pop_back();
temp.left=&leftnode;
TreeNode rightnode;
rightnode=parsetree.back();
parsetree.pop_back();
temp.right=&rightnode;
parsetree.push_back(temp);
}
Your variables leftnode and rightnode have a limited lifespan. Since they are declared in the scope of your if, they will be destroyed once you step out of there. Meaning their adresses become invalid ! So, each time, the content of temp.left and temp.right is going to point to some garbage data.
This is actually why you can see that you find the same address multiple times : since the previous object has been destroyed, it is being used to store the new data that you need. But that's not exactly what you want, since you want to preserve all the objects that you've created.
The easiest way would be to dynamically create the TreeNodes you need (and modify the rest of your code accordingly):
TreeNode *leftnode = new TreeNode;
TreeNode *rightnode = new TreeNode;
That way, they will stay valid even after stepping out of the if.
You must however not forget to delete them afterwards.
来源:https://stackoverflow.com/questions/16073637/temporary-pointer-point-to-a-using-vector-address