Linked List with objects

Hi, i got problems with linked lists with objects.
I created the linked list with data node of integers and it works without any problems, but now that i try it with a class and its objects it doesnt work.
insert and print seems to work properly, the function ~Lista make the exe crash

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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
//List Header:
#ifndef LISTA_H_
#define LISTA_H_

#include <iostream>
#include "Pringles.h"
using namespace std;

class nodeL{
friend class Lista;
friend ostream& operator<<(ostream&, nodeL*&);

public:
	nodeL(Pringles& p) : nextPtr(0) {P.setT(p.getT()); P.setD(p.getD());}
	Pringles getD(){return P;}
private:
	nodeL* nextPtr;
	Pringles P;
};

ostream& operator<<(ostream& out, nodeL* &n){
	out<< (n->getD()).getT();
	return out;
}


class Lista{
public:
	Lista() : firstPtr(0), lastPtr(0), nElem(0) {}
	~Lista();
	void insertAtFront(Pringles& P);
	bool isEmpty() const {if(firstPtr==0) return true; else return false;}
    void insertAtBack(Pringles& P);
    void removeFront();
    void removeBack();
    void print() const;
private:
	nodeL* firstPtr;
    nodeL* lastPtr;
    int nElem;
};

Lista::~Lista(){

	if(!isEmpty()){
	nodeL* current, *temp;
	current=firstPtr;

	 while(current!=0){

		temp=current;

        cout<<"Deleting element: "; cout<< temp <<endl;
		current=current->nextPtr;
        delete &(temp->getD());
		delete temp;
	 }
	}
}

void Lista::print() const{
	if(!isEmpty()){
	nodeL *current;
	current=firstPtr;
	while(current!=0){
		cout<< current <<" ";
		current=current->nextPtr;
	}
	cout<<endl;
	}
}

void Lista::insertAtFront(Pringles& P){
	nodeL* newPtr=new nodeL(P);

	if(isEmpty()){
		firstPtr=lastPtr=newPtr;
	    nElem++;
	}
	else{newPtr->nextPtr=firstPtr;
	     firstPtr=newPtr;
	     nElem++;
	}
    cout<<"Inserted."<<endl;
}

void Lista::insertAtBack(Pringles& P){
	nodeL* newPtr=new nodeL(P);

	if(isEmpty()){
		firstPtr=lastPtr=newPtr;
	    nElem++;
	}
	else{lastPtr->nextPtr=newPtr;
	     lastPtr=newPtr;
	     nElem++;
	}
	cout<<"Inserted."<<endl;
}

void Lista::removeFront(){
	if(!isEmpty()){
	cout<<"Removing from front: ";
	cout<< firstPtr <<endl;
	nodeL* temp;
	temp=firstPtr;
	firstPtr=temp->nextPtr;

	delete temp;
	nElem--;
	cout<<"Removed."<<endl;
	} else cout<<"List empty!"<<endl;
}

void Lista::removeBack(){
	if(!isEmpty()){
	cout<<"Removing from back: ";
	cout<< (lastPtr) <<endl;
	nodeL* current;
	current=firstPtr;
	while((current->nextPtr)!=lastPtr)
		current=current->nextPtr;
	nodeL* temp=lastPtr;
	lastPtr=current;

	delete temp;
	nElem--;
	cout<<"Removed."<<endl;
	} else cout<<"List empty!"<<endl;
}


#endif /* LISTA_H_ */

//Class Header
#ifndef PRINGLES_H_
#define PRINGLES_H_

#include <string>
using namespace std;

class Pringles{
friend ostream& operator<<(ostream&, Pringles&);
friend istream& operator>>(istream&, Pringles&);
public:
	Pringles(int gr=0, string g="none");
	~Pringles();
	int getD(){return Dimension;}
	string getT(){return *Taste;}
	Pringles operator=(Pringles& P);
	void setD(int gr){Dimension=gr;}
	void setT(string g){*Taste=g;}
private:
	int Dimension;
	string* Taste;
};

Pringles::Pringles(int gr, string g){
	Taste=new string(g);

	Dimension=gr;
}

Pringles::~Pringles(){

	delete Taste;
}

Pringles Pringles::operator=(Pringles& P){
	*Taste=P.getT();
	Dimension=P.getD();
	return *this;
}

ostream& operator<<(ostream& output, Pringles& P){
	output<<"Dimension: "<<P.getD()<<" - Taste: "<<P.getT()<<endl;
	return output;
}

istream& operator>>(istream& input, Pringles& P){
	cout<<"Insert dimension: "; input>>P.Dimension;
	cout<<"Insert taste: "; input>>*P.Taste; cout<<endl;
	return input;
}
#endif /* PRINGLES_H_ */

//MainTest
#include "Lista.h"
#include "Pringles.h"
#include <iostream>
using namespace std;

int main(){
    Pringles P1(10,"Classic"),P2(20,"Paprika"),P3(15,"Sauce");

    Lista L;

    L.insertAtFront(P1);
    L.insertAtBack(P2);
    L.insertAtFront(P3);

    L.print();

    L.removeFront();
    L.removeBack();

    L.print();

    return 0;
}
Last edited on
When your line 18 was still int P;, did you have line 55 as delete &(temp->getD());? If not, why the delete is there now?
Line 55 doesn't make sense: the return value of getD() isn't a dynamically allocated object
Thanks for the answers but if i remove line 55 the program still doesnt work :(
why did you make Taste a pointer?
At a point that pointer becomes invalid.

Due to this muliple expression packed in a single line the program becomes nearly undebugable
I made Taste a pointer because i want to use class string and not char* , and at the same time I have to use dynamic allocations

EDIT: i tried without dynamic allocation and it works (but i dont know why i have to put at line 65 lastPtr->nextPtr and not 0 to let it work), while with char* and dynamic allocation the result is worse than before ...

Now i got a question: how can i use both string and dynamic allocation?
Last edited on
I don't see why Taste is supposed to be a pointer.

I found the bug on line 15: the Pringles object is copied to a local object which deletes Taste after beeing used. Therefore the pointer becomes invalid
At the exam i will be forced to use new and delete for string members, this is the reason
Can you be more specific about the bug? i cant find it in line 15

Thank you for the advices!
The result type

Pringles getD(){return P;}

is a copy of P not P itself.

The copy holds the same pointer to Taste as P does.

When the copy goes out of scope its destructor is called and (on line 166) Taste will be destroyed.
Since P and the copy are pointing to the same object Taste within P is now invalid.

Whenever you call getD() of nodeL (like on line 22) Taste will be destroyed

hope you get it?
yes now i got it! I have to work with P reference to avoid this, right?
Thank you so much!
I have to work with P reference to avoid this, right?
Yes, consider using const xxx &. That'd stabilize the whole thing.

tip:
to avoid an unwanted copy of an object (usually when a class contains pointer) overload the operator=() and make it private:
Topic archived. No new replies allowed.