递归函数给出分段错误,如何将指针对象指向它的子对象?
Recursive function gives segmentation fault, how to point a pointer object to it's child?
所以我有一个具有多个节点的 prefixtree 对象。每个节点由一个字符组成,无论它是否是最终节点,它的子节点都存储在一个对象指针数组中(最多 26 个值)。我需要打印在给定节点下找到的单词。
示例如下。
a
/ \
b c
\
t
如果在具有字符 'a' 的节点上调用该函数,它应该打印 ab 并执行。我计划通过添加到字符串直到到达标记为最终的节点然后删除该字母来执行此操作。我想实现一个递归函数,但是当将一个节点设置为该节点的子节点时,出现分段错误。
void PrefixTreeNode::printAllWords() const
{
PrefixTreeNode* node;
for(char i = 'a'; i < 'a' + ALPHABET_SIZE; i++)
{
if(getChild(i) != nullptr)
{
if(!isFinal())
{
nodeList.push_back(i);
cout << "added: " << i << endl;
node = node->getChild(i); //this line results to segmentation fault
node->printAllWords(); //How would I call the function on the node's child?
}
else if(isFinal())
{
nodeList.push_back(i);
cout << nodeList;
nodeList.pop_back();
return;
}
}
}
}
获取子函数:
PrefixTreeNode* PrefixTreeNode::getChild(char c)
{
if (isalpha(c))
return link[tolower(c)-'a'];
else
return nullptr;
}
const PrefixTreeNode* PrefixTreeNode::getChild(char c) const
{
if (isalpha(c))
return link[tolower(c)-'a'];
else
return nullptr;
}
节点对象:
class PrefixTreeNode
{
friend PrefixTree;
private:
char c;
bool final;
PrefixTreeNode* link[ALPHABET_SIZE];
public:
//Constructs a new node
PrefixTreeNode();
//Copy constructor
PrefixTreeNode(const PrefixTreeNode&);
//Copy assignment
const PrefixTreeNode& operator=(const PrefixTreeNode&);
//Returns the character this node contains
char getChar() const { return c; }
//Returns whether this node is the end of a word
bool isFinal() const { return final; }
//Changes whether this node is the end of a word
void setFinal(bool b) { final = b; }
//Returns the node corresponding to the given character
PrefixTreeNode* getChild(char);
//Returns the node corresponding to the given character
const PrefixTreeNode* getChild(char) const;
//Adds a child corresponding to the given character
void addChild(char);
//Removes the child corresponding to the given character
void deleteChild(char);
//TODO: print all words that end at or below this PrefixTreeNode
void printAllWords() const;
//Destructor
~PrefixTreeNode();
};
如果我只告诉你为什么线路是segment fault,我可以说你可以初始化变量节点,在线路上面。
我不知道完整的代码,但我建议把它改成这样。
void PrefixTreeNode::printAllWords() const
{
for(char i = 'a'; i < 'a' + ALPHABET_SIZE; i++)
{
PrefixTreeNode* node = getChild(i);
//if(getChild(i) != nullptr)
if(node != nullptr)
{
nodeList.push_back(i);//this line will be run, ALWAYS whatever the return of isFinal, so I moved it to here.
if(!isFinal())
{
//nodeList.push_back(i); //moved to the front of 'if'
cout << "added: " << i << endl;
//just remove it
//node = node->getChild(i); //this line results to segmentation fault
node->printAllWords(); //How would I call the function on the node's child?
}
//else if(isFinal()) //duplicated
else
{
//nodeList.push_back(i); //moved to the front of 'if'
cout << nodeList; //I don't know the type of nodeList, but you may take care of it.
nodeList.pop_back();
return;
}
}
}
}
所以我有一个具有多个节点的 prefixtree 对象。每个节点由一个字符组成,无论它是否是最终节点,它的子节点都存储在一个对象指针数组中(最多 26 个值)。我需要打印在给定节点下找到的单词。
示例如下。
a
/ \
b c
\
t
如果在具有字符 'a' 的节点上调用该函数,它应该打印 ab 并执行。我计划通过添加到字符串直到到达标记为最终的节点然后删除该字母来执行此操作。我想实现一个递归函数,但是当将一个节点设置为该节点的子节点时,出现分段错误。
void PrefixTreeNode::printAllWords() const
{
PrefixTreeNode* node;
for(char i = 'a'; i < 'a' + ALPHABET_SIZE; i++)
{
if(getChild(i) != nullptr)
{
if(!isFinal())
{
nodeList.push_back(i);
cout << "added: " << i << endl;
node = node->getChild(i); //this line results to segmentation fault
node->printAllWords(); //How would I call the function on the node's child?
}
else if(isFinal())
{
nodeList.push_back(i);
cout << nodeList;
nodeList.pop_back();
return;
}
}
}
}
获取子函数:
PrefixTreeNode* PrefixTreeNode::getChild(char c)
{
if (isalpha(c))
return link[tolower(c)-'a'];
else
return nullptr;
}
const PrefixTreeNode* PrefixTreeNode::getChild(char c) const
{
if (isalpha(c))
return link[tolower(c)-'a'];
else
return nullptr;
}
节点对象:
class PrefixTreeNode
{
friend PrefixTree;
private:
char c;
bool final;
PrefixTreeNode* link[ALPHABET_SIZE];
public:
//Constructs a new node
PrefixTreeNode();
//Copy constructor
PrefixTreeNode(const PrefixTreeNode&);
//Copy assignment
const PrefixTreeNode& operator=(const PrefixTreeNode&);
//Returns the character this node contains
char getChar() const { return c; }
//Returns whether this node is the end of a word
bool isFinal() const { return final; }
//Changes whether this node is the end of a word
void setFinal(bool b) { final = b; }
//Returns the node corresponding to the given character
PrefixTreeNode* getChild(char);
//Returns the node corresponding to the given character
const PrefixTreeNode* getChild(char) const;
//Adds a child corresponding to the given character
void addChild(char);
//Removes the child corresponding to the given character
void deleteChild(char);
//TODO: print all words that end at or below this PrefixTreeNode
void printAllWords() const;
//Destructor
~PrefixTreeNode();
};
如果我只告诉你为什么线路是segment fault,我可以说你可以初始化变量节点,在线路上面。
我不知道完整的代码,但我建议把它改成这样。
void PrefixTreeNode::printAllWords() const
{
for(char i = 'a'; i < 'a' + ALPHABET_SIZE; i++)
{
PrefixTreeNode* node = getChild(i);
//if(getChild(i) != nullptr)
if(node != nullptr)
{
nodeList.push_back(i);//this line will be run, ALWAYS whatever the return of isFinal, so I moved it to here.
if(!isFinal())
{
//nodeList.push_back(i); //moved to the front of 'if'
cout << "added: " << i << endl;
//just remove it
//node = node->getChild(i); //this line results to segmentation fault
node->printAllWords(); //How would I call the function on the node's child?
}
//else if(isFinal()) //duplicated
else
{
//nodeList.push_back(i); //moved to the front of 'if'
cout << nodeList; //I don't know the type of nodeList, but you may take care of it.
nodeList.pop_back();
return;
}
}
}
}