【发布时间】:2015-01-22 06:02:47
【问题描述】:
我有一个使用 std::vector 实现的 n 路树。 Node 类只保存指向根元素的指针,而 Link 类有一个 std::vector 指向自身的指针。我在创建每个链接时命名了它们,但是当我尝试使用链接名称在此树中定位节点时却出现分段错误。我也意识到我的函数 GetLink() 没有做任何错误检查,我尝试了几件事,但它们没有工作,所以如果可能的话,如果有任何关于如何在这种情况下实现它的建议,将不胜感激。这是我的代码:
// in node.h
class Node {
public:
// constructors
// fuctions
private:
Link *root;
};
// in link.h
class Link {
public:
//EDIT: added vector initialization in the constructor
Link() : my_links(0) { }
// some functions
// EDIT: example of making the tree
bool Load(token) {
// parsing code based on token
else if (strcmp (temp, "link") == 0)
{
Link* lnk = new Link ();
lnk->Load (token);
lnk->Init ();
AddChild (lnk);
lnk->m_parent = this;
}
// some more parsing code
}
void Link::AddChild (Link* pChild)
{
my_links.push_back(pChild);
}
Link* Link::GetLink(char* str) // this is the function that is the problem.
{
if (strcmp(name, str) == 0)
{
return this;
}
for (int i=0; i < (int) my_links.size(); i++)
{
//Edit: added check for NULL ptr
if (my_links[i] == NULL)
{
fprintf (stderr, "\n\t Couldn't find link\n\n");
break;
}
//Edit: typo corrected
return my_links[i]->GetLink(str);
}
}
private:
char name[256];
Link* m_parent;
std::vector<Link*> my_links;
};
// in main.cpp
static Node* node;
static Link* link;
main()
{
char *str = "link_3";
link = node->GetLink(str);
printf("\n found link: %s", link->GetName());
retrun 0;
}
编辑:将早期代码重写为 MCVE
#include <cstdio>
#include <vector>
#include <cstring>
class Link {
public:
//EDIT: added vector initialization in the constructor
Link() : my_links(0)
{
m_parent = NULL;
}
void SetParent(Link* pParent)
{
m_parent = pParent;
}
// EDIT: example of making the tree
bool Load(char *str)
{
unsigned int len;
Link* lnk = new Link ();
len = strlen(str);
strcpy(name, str);
lnk->SetParent(this);
AddChild (lnk);
return true;
}
void AddChild (Link* pChild)
{
my_links.push_back(pChild);
}
Link* GetLink(char* str) // this is the function that is the problem.
{
if (strcmp(name, str) == 0)
{
return this;
}
for (int i=0; i < (int) my_links.size(); i++)
{
//Edit: added check for NULL ptr
if (my_links[i] == NULL)
{
fprintf (stderr, "\n\t Couldn't find link\n\n");
break;
}
//Edit: typo corrected
return my_links[i]->GetLink(str);
}
fprintf(stderr, "\n\t Cannot get link\n\n");
return 0;
}
char* GetName()
{
return name;
}
private:
char name[256];
Link* m_parent;
std::vector<Link*> my_links;
};
class Node {
public:
Node()
{
root = NULL;
}
bool Load (char *str)
{
unsigned int len;
root = new Link(); // here is where the error occurs
len = strlen(str);
strcpy(name, str);
return true;
}
void AddChild (char *str)
{
root->Load(str);
}
Link* GetRoot()
{
return root;
}
private:
char name[256];
Link *root;
};
static Node* node;
static Link* lnk;
int main()
{
node->Load((char*)"I am root");
node->AddChild((char*)"I am child 1");
node->AddChild((char*)"I am child 2");
node->AddChild((char*)"I am child 3");
char *str = (char*)"I am child 2";
lnk = node->GetRoot()->GetLink(str);
printf("\n found link: %s", lnk->GetName());
return 0;
}
我现在在 VS2010 的第 77 行遇到错误,即 Node 类中的“root = new Link()”,Load() 函数是:
Unhandled exception at 0x012e1bbe in nWayTree.exe: 0xC0000005: Access violation writing location 0x00000100.
【问题讨论】:
-
如果你使用
std::vector,你写的不是C,所以不要用C标记你的问题。 -
你还没有初始化
vector的大小。要么push_back所有Link指针,要么在构造函数中初始化vector的大小。因此,my_links.size()给出了分段错误。 -
@ShauryaChats 我在构造函数中初始化向量,并有一个通过 push_back 添加子项的函数,为了简洁起见,我没有在此处包含它。
-
似乎内存管理会很痛苦。在你的向量中使用 boost::optional 或 boost::any。或智能指针,如
unique_ptr。这将使您不必手动关心 RAII。 -
好的。另外,我认为您应该尝试在
GetLink()中添加终止条件,以使Link*等于NULL。