Having trouble using pointers with classes

So I am getting a segmentation fault at

tech_name = new char[strlen(temp)+1];
strcpy(*tech_name, temp);

in my input function, and I'm not sure if I am handling my pointers/variables correctly. Any input is very much appreciated, and because it is multiple files I have put "*************************************" between them to make them easily identifiable.


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
133
134
135
136
137
138
139
140
141
142
143
144

#include "class.h"

int main()
{
        int howmany;
        tech_list * tech;
        cout << "How many items would you like to input?" << endl;
        cin >> howmany;
        tech_list(howmany);
        cout << "Please enter the items." << endl;
        for(int i = 0; i < howmany; i++)
{
        tech[i].input();
}

        for(int i = 0; i < howmany; i++)
{
        tech[i].display();
}
        return 0;
}


*************************************************************************

#include "class.h"

Tech::Tech()
{
        tech_name = NULL;
        tech_desc = NULL;
        cost = NULL;
        pro = NULL;
        con = NULL;
        rating = NULL;
}

tech_list(int howmany)
{
num_items = 0;
tech = new list[howmany + 1];
}

void tech_list::input()
{
        cout << "We are working with item #: "
                <<num_items+1 << endl;
        tech[num_items].input();
        ++num_items;
}

void Tech::input()
{

        char temp[200] = {0};
        cout << temp << endl;
        cout << "Please enter the items name: ";
        cin.getline(temp, 200, '\n'); cin.ignore(200, '\n');
        char tech_name = new char[strlen(temp)+1];
        strcpy(tech_name, temp);
        memset(temp, 0, strlen(temp));

        cout << "Please enter the item description: ";
        cin.getline(temp, 200, '\n'); cin.ignore(200, '\n');
        char tech_desc = new char[strlen(temp)+1];
        strcpy(tech_desc, temp);
        memset(temp, 0, strlen(temp));

        cout << "Please enter the cost of the item: " << endl;
        float cost = new float;
        cin >> *cost; cin.ignore();

        cout << "Please enter the item's best advantage: ";
        cin.getline(temp, 200, '\n'); cin.ignore(200, '\n');
        char pro = new char[strlen(temp)+1];
        strcpy(pro,temp);
        memset(temp, 0, strlen(temp));

        cout << "Please enter the item's worst disadvantage: ";
        cin.getline(temp, 200, '\n'); cin.ignore(200, '\n');
        char con = new char[strlen(temp)+1];
        strcpy(con,temp);
        memset(temp, 0, strlen(temp));

 	cout << "Please rate the item from 1 to 5 stars: ";
        float rating = new float;
        cin >> *rating; cin.ignore();

}

void tech_list::display()
{
        for(int i = 0; i<num_items; ++i)
                tech[num_items].display();
}

void Tech::display()
{
        cout << tech_name << '\t' << tech_desc << '\t' << "This item costs: " << cost << "dollars." << '\t' << "The best advantage is: " << pro << '\t' << "The worst disadvantge is: " << con << '\t' << "You rated it: " << rating << endl;
}

********************************************************************

#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;

class Tech
{
        public:
                Tech();
                ~Tech();
                void Add(Tech & to_add);
                void input();
                void Edit(char to_modify[]);
                void display();
                void Display_benefit(char item_name[]);
                void Display_con(char item_name[]);

        private:
                char *tech_name;
                char *tech_desc;
                float *cost;
                char *pro;
                char *con;
                float *rating;
};

class tech_list
{
        public:
                list(int howmany);
                ~list();
                void Add(Tech& to_add);
                void input();
                void display();

        private:
                Tech *tech;
                int num_items;
};


My errors are as follows:

Main.cpp: In function ‘int main()’:
Main.cpp:9:14: error: conflicting declaration ‘list howmany’
tech_list(howmany);
^
Main.cpp:5:6: note: previous declaration as ‘int howmany’
int howmany;
^~~~~~~


class.h:31:3: error: tech_list::tech_list(int)
tech_list(int howmany);
^~~~
Prog4.cpp:15:6: error: expected ')' before 'int'

Last edited on
> strcpy(*tech_name, temp);
Yes, remove the * from the pointer.

Why are you using char pointers, and not std::string for everything.


> list::list(int &howmany)
Your header file just said 'int', not 'int&'.

sorry those were a few dumb mistakes I fixed after posting and have since touched up, also my class doesn't want us to use strings yet. We're still trying to start from the bottom I guess. Despite changing it from reference to by value, it's still not letting me pass it saying the same 3 errors
Main.cpp:9:14: error: conflicting declaration ‘list howmany’
list(howmany);
^
Main.cpp:5:6: note: previous declaration as ‘int howmany’
int howmany;
^~~~~~~
prog4.cpp:15:6: error: expected unqualified-id before ‘int’
list(int howmany)
^~~
prog4.cpp:15:6: error: expected ‘)’ before ‘int’
is "list" part of namespace std and causing you trouble?

I just changed every instance of list, to tech_list and it is still having the same errors. I will change the name to tech_list in the source code to reflect this and prevent any confusion.
Well, first of all your Tech* tech is still a pointer when you try to do some data manipulation. That's why the dynamic allocation crashed the program by giving a seg fault... You seem to be working with two pointers: Tech* tech and list* tech, but you only dynamically allocate one of them (which is in main).
okay that makes sense, but would changing

tech_list(int howmany)
{
num_items = 0;
tech = new tech_list[howmany + 1];
}

to

tech_list(int howmany)
{
num_items = 0;
tech_list *tech = new Tech[howmany + 1];
}
initialize it?
or would it be

tech_list(int howmany)
{
num_items = 0;
Tech *tech = new Tech[howmany + 1];
}
because I am trying to access the private of Tech
I would test it, but unfortunately I am still not able to pass the int howmany through the constructor so I can allocate it dynamically, and I'm still not sure why.
Last edited on
In your main, you manually called the constructor of tech_list. It's perfectly legal to call constructors, but you should not call them.

In your main, your tech_list is a pointer, so anything in your for loops are working with an an initialized pointer.

stealthy12341 wrote:

tech_list(int howmany)
{
num_items = 0;
tech = new tech_list[howmany + 1];
}

to

tech_list(int howmany)
{
num_items = 0;
tech_list *tech = new Tech[howmany + 1];
}
initialize it?
or would it be

tech_list(int howmany)
{
num_items = 0;
Tech *tech = new Tech[howmany + 1];
}

Remove the +1. Here is a code snippet from your main.cpp
1
2
3
4
5
6
7
8
9
int howmany;
cout << "How many items would you like to input?" << endl;
cin >> howmany;
tech_list * tech = new tech_list(howmany);
cout << "Please enter the items." << endl;
for(int i = 0; i < howmany; i++)
{
  tech[i].input();
}

With this code, you are looping through an array of objects. This is a bit weird because you also have:
1
2
3
4
5
tech_list::tech_list(int howmany)
{
  num_items = 0;
  tech = new Tech[howmany + 1];
}

which makes me think you're going to also loop through this list. I am sure you are not suppose to dynamically allocate tech_list in main, but dynamically allocate the pointer within the class of tech_list.

I am not 100% what your main.cpp will look like, but I think this should capture the idea
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main()
{
  int howmany;
  cout << "How many items would you like to input?" << endl;
  cin >> howmany;

  // tech_list tech(howmany) will dynamically allocate the pointer. This
  // pointer will act like a list.
  tech_list tech(howmany);

  cout << "Please enter the items." << endl;
  for(int i = 0; i < howmany; i++) {
    // In this for loop, you will go through the list and get item information
    // and such.
    tech.input();
  }

  for(int i = 0; i < howmany; i++) {
    // Similar to above, loop through the list (which are just pointers) and
    // print them.
    tech.display();
  }
  return 0;
}

In short, I think you are confusing which object to dynamically allocate. Dynamically allocate your pointer that belongs to the class tech_list before working on other parts of the code.
So I think I get what you're saying, and thank you for taking the time to help a noob out. but I'm still having some trouble. here's what I'm trying, and now it's giving me an error about the period for tech.

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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "class.h"

int main()
{
        int howmany = 0;
        cout << "How many items would you like to input" << endl;
        cin >> howmany;
        tech_list tech[howmany];

        cout << "Please enter the items." << endl;

        for(int i = 0; i< howmany; i++)
        {
                cout << "We are working with item #: "
                        << i + 1 << endl;
                Tech.input();
        }


        for(int j = 0; j < howmany; j++)
{
        Tech.display();
}
        return 0;
}

****************************************************************************

#include "class.h"

Tech::Tech()
{
        tech_name = NULL;
        tech_desc = NULL;
        cost = NULL;
        pro = NULL;
        con = NULL;
        rating = NULL;
        num_items = 0;
}

tech_list::tech_list()
{
        tech = NULL;

}

Tech::~Tech()
{
        delete tech_name;
        delete tech_desc;
        delete cost;
        delete pro;
        delete con;
        delete rating;
}

tech_list::~tech_list()
{
        delete tech;
}

void Tech::input()
{

        char temp[200] = {0};
        cout << "Please enter the items name: ";
        cin.getline(temp, 200, '\n'); cin.ignore(200, '\n');
        char *tech_name = new char[strlen(temp)+1];
        strcpy(tech_name, temp);

        char temp1[200] = {0};
        cout << "Please enter the item description: ";
        cin.getline(temp1, 200, '\n'); cin.ignore(200, '\n');
        char *tech_desc = new char[strlen(temp1)+1];
        strcpy(tech_desc, temp1);


        cout << "Please enter the cost of the item: " << endl;
        cost = new float;
        cin >> *cost; cin.ignore();

        char temp2[200] = {0};
        cout << "Please enter the item's best advantage: ";
        cin.getline(temp2, 200, '\n'); cin.ignore(200, '\n');
        char *pro = new char[strlen(temp)+1];
        strcpy(pro,temp2);
	
	
        char temp3[200] = {0};
        cout << "Please enter the item's worst disadvantage: ";
        cin.getline(temp, 200, '\n'); cin.ignore(200, '\n');
        char *con = new char[strlen(temp3)+1];
        strcpy(con,temp3);


        cout << "Please rate the item from 1 to 5 stars: ";
        rating = new float;
        cin >> *rating; cin.ignore();

}

void Tech::display()
{
        cout << *tech_name << '\t' << *tech_desc << '\t' << "This item costs: " << *cost << "dollars." << '\t' << "The best advantage is: " << *pro << '\t' << "The worst disadvantge is: " << *con << '\t' << "You rated it: " << *rating << endl;
}

void Tech::search(char tech_name[])
{
}

**********************************************************************

#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;


class Tech;

class tech_list
{
        public:
                tech_list();
                ~tech_list();

        private:
                Tech *tech;
                Tech* link;
};
class Tech
{
        public:
                Tech();
                ~Tech();
                void Add(Tech & to_add);
                void input();
                void Edit(char to_modify[]);
                void display();
                void search(char tech_name[]);
                void Display_pro();
                void Display_con();

        private:
                char *tech_name;
                char *tech_desc;
                float *cost;
                char *pro;
                char *con;
                float *rating;
                int num_items;
                tech_list* link;
};



So I tried something different, and it is saying that my list is private within this context, but I have linked the classes so I wouldn't think that would matter.

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
#include "class.h"

int main()
{
        int howmany = 0;
        cout << "How many items would you like to input" << endl;
        cin >> howmany;
        tech_list tech[howmany];

        cout << "Please enter the items." << endl;

        for(int i = 0; i< howmany; i++)
        {
                cout << "We are working with item #: "
                        << i + 1 << endl;
                Tech::input(tech_list::tech);
        }


        for(int j = 0; j < howmany; j++)
{
        Tech::display(tech_list::tech);
}
        return 0;
}


and I get

Main.cpp:16:26: error: ‘Tech* tech_list::tech’ is private within this context
Tech::input(tech_list::tech);
^~~~
In file included from Main.cpp:1:0:
class.h:16:9: note: declared private here
Tech *tech;
^~~~
Main.cpp:16:26: error: invalid use of non-static data member ‘tech_list::tech’
Tech::input(tech_list::tech);
^~~~
In file included from Main.cpp:1:0:
class.h:16:9: note: declared here
Tech *tech;
^~~~
Main.cpp:22:27: error: ‘Tech* tech_list::tech’ is private within this context
Tech::display(tech_list::tech);
^~~~
In file included from Main.cpp:1:0:
class.h:16:9: note: declared private here
Tech *tech;
^~~~
Main.cpp:22:27: error: invalid use of non-static data member ‘tech_list::tech’
Tech::display(tech_list::tech);
^~~~
In file included from Main.cpp:1:0:
class.h:16:9: note: declared here
Tech *tech;



even though I have
tech_list* link;
in the class tech and
Tech* link;
in class tech_list

sorry if this is a lot of stuff to be posting, I just genuinly want to understand and be able to use these concepts, while understanding what the syntax means.
Last edited on
First, let's take a look at your void tech_list::input()
1
2
3
4
5
6
7
void tech_list::input()
{
        cout << "We are working with item #: "
                <<num_items+1 << endl;
        tech[num_items].input();
        ++num_items;
}

It doesn't quite make sense to do ++num_items. You called this function after you instantiated the object inside main, so I assume that this function is called right after any object of the class is instantiated. I think you are meaning to use a loop here instead.
1
2
3
4
5
6
7
void tech_list::input()
{
  for(int i = 0; i < num_items; i++) {
    cout << "We are working with item #: " << i+1 << endl;
    tech[i].input();
  }
}

and therefore your main.cpp will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
  int howmany;
  cout << "How many items would you like to input?" << endl;
  cin >> howmany;
  cin.ignore();

  // Instantiate object tech of tech_list with it's member Tech having list
  // size of howmany
  tech_list tech(howmany);

  cout << "Please enter the items." << endl;
  // tech.input() will loop through until we have entered all items as per the
  // size
  tech.input();

  // Display the text
  tech.display();
  return 0;
}

Your tech_list tech in main is not suppose to be an array. Or at least I don't think it is. It just doesn't make sense to me to have a list of lists. Shouldn't one list be enough?

Tech::~Tech isn't deleting arrays correctly. If you dynamically allocate an array, you must deallocate them properly as well. Only two of the pointers are deallocated properly (the non char arrays).

This is what your tech_list::tech_list(int howmany) should look like (or similar):
1
2
3
4
5
tech_list::tech_list(int howmany) 
{
  num_items = howmany;       // The list calls for the size to be equal to howmany
  tech = new Tech[howmany]; // Let's dynamically allocate an array that can hold "howmany" things.
}


Also, you don't need cin.ignore() after you use getline(). It just makes the program pause such that you'll have press the enter key again, which can be annoying.

If you fix everything, you should get:

$ g++ main.cpp class.cpp -Wall -Wextra -o "program.out"
$ ./program.out 
How many items would you like to input?
3
Please enter the items.
We are working with item #: 1

Please enter the items name: Pencil
Please enter the item description: It's a bright yellow no. 2 pencil.
Please enter the cost of the item: 
0.99 
Please enter the item's best advantage: Can write things.
Please enter the item's worst disadvantage: Has to sharpen every once a while.
Please rate the item from 1 to 5 stars: 3
We are working with item #: 2

Please enter the items name: Danish Pastry
Please enter the item description: Sweet, savory snacks 
Please enter the cost of the item: 
3.99
Please enter the item's best advantage: It's good
Please enter the item's worst disadvantage: None
Please rate the item from 1 to 5 stars: 5
We are working with item #: 3

Please enter the items name: Multivitamin pill
Please enter the item description: For those who skip lunch
Please enter the cost of the item: 
1.99
Please enter the item's best advantage: Keeps you somewhat healthy?
Please enter the item's worst disadvantage: It's a pill
Please rate the item from 1 to 5 stars: 3
Name: Pencil
Description: It's a bright yellow no. 2 pencil.
Cost: 0.99
Pros: Can write things.
Cons: Has to sharpen every once a while.
Rated: 3
Name: Danish Pastry
Description: Sweet, savory snacks
Cost: 3.99
Pros: It's good
Cons: None
Rated: 5
Name: Multivitamin pill
Description: For those who skip lunch
Cost: 1.99
Pros: Keeps you somewhat healthy?
Cons: It's a pill
Rated: 3
$ 


In your current main, you are trying to array tech. You should not and cannot. Use the members of tech_list to access the private member instead, which is shown above. It's done via the function tech_list::input().
Topic archived. No new replies allowed.