Segfault reading member string

Hello everyone! I have an error in my class. I'm suspect it's something simple, maybe me failing to understand how strings are created and passed to my constructor. In getName() my function prints 1 and then segfaults before printing 2. I'll include the code below. Thank you in advance for providing such a helpful forum. - Craig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// A node in a taxonomic tree.

#include <iostream>
#include <string>
#include <map>
using std::string;
using std::map;
using std::cout;
using std::endl;

class Taxon
{
	public:
		Taxon(string name, Taxon* parent = NULL);
		~Taxon();
		void addChild(Taxon* child);
		Taxon* getChild(string name);
		Taxon* getParent();
		int childCount();
		string getName();
		string getCommonName();
	private:
		map<string, Taxon*> children;
		Taxon* parent;
		string name;
		string commonName;
		string author;
		string region;
		bool exinct;
};

Taxon::Taxon(string name_, Taxon* parent_)
{
	parent = parent_;
	if(parent != NULL)
	{
		parent->addChild(this);
	}
	name = name_;
}

Taxon::~Taxon()
{
	//stl probably handles this automatically
}

void Taxon::addChild(Taxon* child)
{
	children[child->name] = child;
}

Taxon* Taxon::getChild(string name)
{
	return children[name];
}

int Taxon::childCount()
{
	return children.size();
}

Taxon* Taxon::getParent()
{
	return parent;
}

string Taxon::getName()
{
	cout << "1" << endl;
	return name;
	cout << "2" << endl;
}

string Taxon::getCommonName()
{
	return commonName;
}

int main(int argc, char** argv)
{
	Taxon* animalia = new Taxon("Animalia");
	Taxon* chordata = new Taxon("Chordata", animalia);
	Taxon* child = animalia->getChild("Chordata");
	string childname = child->getName();
}

Line 84 calls getName() which prints the 1, then segfaults before printing the 2.
Line 71 will never execute because the function will return first. ;o)

You need to set the name *before* you add your child in the constructor:

1
2
3
4
5
6
7
8
9
10
Taxon::Taxon(string name_, Taxon* parent_)
{
	parent = parent_;
	name = name_; // here - before the name is used in the children vector
	if(parent != NULL)
	{
		parent->addChild(this);
	}
	// name = name_; // not here - too late
}


But those variable should really be set in the ctor-initializer:


1
2
3
4
5
6
7
8
9
10
11
Taxon::Taxon(string name_, Taxon* parent_)
: parent(_parent)
, name(_name)
{
	// now the object integrity is intact allowing more complex
	// operations to be performed safely.
	if(parent != NULL)
	{
		parent->addChild(this);
	}
}

Last edited on
Topic archived. No new replies allowed.