passing string data to a class function segfaults

Jan 30, 2009 at 10:36pm
We have defined a Tool class that has private variables accessed through get and set functions which are public.

The setname function is prototyped as :
void setname(const char * val);
in the header file.

in the cpp file:
void Tool::setname(const char * val)
{
strcpy(name, val);
}

i then make an array of the class by saying:
Tool catalog[60];
int toolindex = 0;


however when we pass name to the function like
catalog[toolindex].setname("make this the name\0");

the program segfaults. I wrote a driver file for my tool class which made an object and set the values of each variable in the private data section of the class, then it output the class values to the screen just fine. Worked great then, but now it seems that it doesnt like the fact that I have an array of tools.. im not sure whats going on here.

Any input would be appreciated!

Jan 30, 2009 at 10:40pm
if we comment out the strcpy line it seems to function.. so perhaps there's a better way to perform this task than with strcpy??
Jan 30, 2009 at 10:52pm
The first argument to strcpy is the destination string, which you've called "name", but you didn't show how you declared it.

If name is declared as [code=c]char name[50];[/code], then it shouldn't crash.
But if name is declared as [code=c]char *name;[/code], then it is probably an unitialized pointer that points into bogus memory, and will cause a segfault.

How did you declare name?
Jan 30, 2009 at 11:04pm
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
class Tool
{
public:
	Tool();
	~Tool();
	int getnumber();
	void setnumber(int val);
	char * getname();
	void setname(const char * val);
	char * getdesc();
	void setdesc(char * val);
	float getlength();
	void setlength(float val);
	float getdiam();
	void setdiam(float val);
	float gettip();
	void settip(float val);
	char * gettype();
	void settype(char * val);
	float getflutelen();
	void setflutelen(float val);
	int getflutenum();
	void setflutenum(int val);
	char * getmaterial();
	void setmaterial(char * val);
	void output();

private:
	int number;
	char* name;
	char* description;
	float length;
	float diameter;
	float tip;
	char* type;
	float flute_length;
	int flute_number;
	char* material;
};


I have the name variable declared as a private char * in my class declaration within the header file.

here is the accompanying cpp file:
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <iostream>
#include <iomanip>
#include <string>
#include "shopdoc_tool.h"
using namespace std;

Tool::Tool()
{
	number= 0;
	name = "Default";
	description = "";
	length = 0.0;
	diameter= 0.0;
	tip = 0.0;
	type = "";
	flute_length = 0.0;
	flute_number = 0;
	material = "";
}

Tool::~Tool()
{
}

int Tool::getnumber()
{
	return number;
}
void Tool::setnumber(int val)
{
	number = val;
}

char * Tool::getname()
{
	return name;
}
void Tool::setname(const char* val)
{
	//string newname;
	//newname.assign(val);
	strcpy(name, val);
}

char * Tool::getdesc()
{
	return description;
}
void Tool::setdesc(char * val)
{
	strcpy(description, val);
}

float Tool::getlength()
{
	return length;
}
void Tool::setlength(float val)
{
	length = val;
}

float Tool::getdiam()
{
	return diameter;
}
void Tool::setdiam(float val)
{
	diameter = val;
}

float Tool::gettip()
{
	return tip;
}
void Tool::settip(float val)
{
	tip = val;
}

char * Tool::gettype()
{
	return type;
}
void Tool::settype(char * val)
{
	strcpy(type, val);
}			

float Tool::getflutelen()
{
	return flute_length;
}
void Tool::setflutelen(float val)
{
	flute_length = val;
}

int Tool::getflutenum()
{
	return flute_number;
}
void Tool::setflutenum(int val)
{
	flute_number = val;
}

char * Tool::getmaterial()
{
	return material;
}
void Tool::setmaterial(char * val)
{
	strcpy(material , val);
}

void Tool::output()
{
	cout.precision(3);
	cout << setiosflags(ios::fixed);
	cout << "Tool Number: 		" << number << endl;
	cout << "Tool Name:		" << name << endl;
	cout << "Tool Description:	" << description << endl;
	cout << "Tool Length:		" << length << endl;
	cout << "Tool Diameter:		" << diameter << endl;
	cout << "Tool Tip Angle:		" << tip << endl;
	cout << "Tool Type:		" << type << endl;
	cout << "Flute Length:		" << flute_length << endl;
	cout << "Number of Flutes:	" << flute_number << endl;
	cout << "Tool Material:		" << material << endl;
	cout << resetiosflags(ios::fixed);
}
Feb 3, 2009 at 7:12pm
You have a few problems here. They are related to the way your managing memory. Your not doing any allocations and de-allocations correctly.

That being said, I don't think it's suitable for you to be using char* variable types. You'd be much better off using the string variable type.

1
2
3
string someValue = "bob";
string newValue = "tony";
someValue = newValue;


Functions like strcpy() etc are highly discouraged as they do no bounds checking. In your case, you've failed to allocate memory to your pointers, thus creating buffer overflows.
Topic archived. No new replies allowed.