I need help with a return value for one of the leetcode questions I am attempting. I am instantiate a structure and then return the pointer to the structure.
TreeNode* deserialize(string data) {
TreeNode r(data[0] - '0');
TreeNode* root = &r;
return root;
}
But this gives me the error "stack use after scope"
I even tried to define root as a member variable to the class where this function is defined and I get "stack buffer overflow".
Here's the definition of TreeNode,
Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
Problem #297
CodePudding user response:
Variables only exist in their respective scope. The scope of your variable r
is the function deserialize
, meaning that the memory automatically allocated on the stack upon entering the function will be deallocated upon leaving it.
The pointer to this structure you are returning will then be dangling, which means that it will point to uninitialized memory and may no longer be used.
To solve your problem, you will need this code:
TreeNode* deserialize(string data) {
return new TreeNode(data[0] - '0');
}
This will allocate the TreeNode instance on the heap and return a pointer to it. It will remain there, until you free it explicitely with delete
, which you must do, unless you want your application to leak memory.
CodePudding user response:
The problem is that you are creating r
within the function deserialize()
, essentially creating r
on deserialize()
stack and then returning a pointer to that object. However, after you exit deserialize()
scope, it cleans up its stack, destroying r
meaning that the pointer to r
that you are returning is no longer pointing to a valid object and is instead points to uninitialized memory.
To fix this you need to use a heap allocated resource so you can maintain its lifetime beyond the deserialize()
scope. You can use new
but this means you have to manually manage the resources memory with new/delete
pairs throughout the code which is super error prone. I would use std::shared_ptr
so the resource is automatically allocated and deleted. std::shared_ptr
has the added benefit of allowing you to have multiple copies of the resource.
#include <memory>
std::shared_ptr<TreeNode> deserialize(std::string data)
{
auto root = std::make_shared<TreeNode>(data[0] - '0');
return root;
}