Solved

small compiler error with linked lists

Posted on 2002-05-13
20
195 Views
Last Modified: 2010-04-02
i'm working on a project for school.. i have to use linked lists to input fractions from a file and compute their mean, standard deviation, search for a number in the file, add a number to the file, remove a number...

i am pretty much done with it except for some minor changes.
i am not very comfortable with linked lists or the -> operator so this might just be a minor problem..
the code is rather long to post here so you can get it at
http://gdstudios.hypermart.net/code.zip

i get the following 2 errors at compile time
95 list.cpp no match for `Fraction & == Fraction &'
140 list.cpp no match for `Fraction & == Fraction &'


the number in the line number and then the file name

p.s.
if your wondering wat i was trying to do with class Node and class List, i dont really know myself.. just trying to get it to work
if i made the member variables of class Node protected i got several strange errors so i decided it was best to leave them public

and i am using the GNU compiler
0
Comment
Question by:grfik
  • 9
  • 8
  • 2
  • +1
20 Comments
 
LVL 4

Expert Comment

by:mblat
ID: 7007529
Well, I compiled it with VC++ and got more than 2 errors. :-(.

The reason for all of them seems to be that you don;t have operator == defined for Fraction.

Something like
   bool operator == (const Fraction& other)
   {
       return ((n == other.n) && (d == other.d));
   }


Note that this is solution for compiler error only - has nothing to do with anything else....

Hope it helps...
0
 

Author Comment

by:grfik
ID: 7007581
umm it gave errors mainly that it should take 2 parameters.. i fixed it and got 2 linker erros, dont know why

..\list.o(.text+0xa31):list.cpp: undefined reference to `operator==(Fraction const &, Fraction const &)'
..\list.o(.text+0xc01):list.cpp: undefined reference to `operator==(Fraction const &, Fraction const &)'
0
 
LVL 4

Expert Comment

by:mblat
ID: 7007600
or, well... in a form I put it you should make it memeber of a Fraction class....

class Fraction
{
....

bool operator== ( ....)
{
....
}
};

otherwise declare it as
class Fraction
{
....

 friend bool operator ==(const Fraction& first, const Fraction& second) ;
}

and put implementation in .cpp

0
 
LVL 2

Expert Comment

by:LoungeLizard
ID: 7007646
As mblat said, the problem is that you're trying to compare *classes* of type Fraction, and the compiler cannot find a way (i.e. a == method) of doing that. You have two options:

1. Implement a operator== for your Fraction class (this is the 00P way - may the force be with you :) It can be an inline function in your Fraction.h header file:

2. Use

if (point->data.getNumber() == data.getNumber())
{
....
}

However, be careful of the second approach - rounding errors could result in some peculiar behaviour


0
 

Author Comment

by:grfik
ID: 7007713
i put it in the class Fraction with 2 parameters and it did work
strangely though.. the runtime results are really unexpected(which is sorta expected)
1- the last fraction from the inputfile is for some reason read twice and another linked list is created to store it
e.g.: inputfile would contain 1/2 2/3 3/4
but when i save the file it would save 1/2 2/3 3/4 3/4
i traced the problem to the input of the file but have no idea how to fix it.
2- when a fraction is removed from the list, its sometimes replaced by a number like 2237608/1
i have a hunch that all that pointing probably causes that :( and since i dont know how to use them well i dont know exactly how to fix it


because these new problems have popped up i am increasing the points
0
 

Author Comment

by:grfik
ID: 7007715
o and i have posted the most up-to-date version of the program at http://gdstudios.hypermart.net/code2.zip

it contains the changes i talked about before and some other things were cleaned up..
0
 
LVL 1

Accepted Solution

by:
jdrescher earned 200 total points
ID: 7008643
One problem is in the following code in List::remove()
 
delete point;
point = head;

if (0 == position)
{
    head = head->next;
    delete point;
}

Node* temp = point->next;
point->next = temp->next;
delete temp;

The first delete point deletes the node from the list without removing it from the list. Then it sets point to the head of the list. The next statement checks if point was at the head of the list and if so it deletes it again. But this time it updates the list so the element is removed. However, the first delete allready trashed the head of the list so head->next could contain invalid data. Then the rest of the code trys to remove the node again. So this code would try to delete a head of the list 3 times...

I just looked at the rest of the remove function and you call  delete point again just before the return. Remove this line!


You should do the following: Decide if the node is the head, tail or otherwise and provide code to remove it for each case. The decision should be like this:

if ( point == head ) {
// head node!
}
else
if ( point->next == NULL )
{
// Tail node
}
else
{
// Interior node!
}

John
0
 
LVL 1

Expert Comment

by:jdrescher
ID: 7008662
In List::add() what is "delete point;" for?
0
 
LVL 1

Expert Comment

by:jdrescher
ID: 7008668
In saveFile() what is "delete point;" for? Remove it and the one in List::add().
0
 
LVL 1

Expert Comment

by:jdrescher
ID: 7008726
I think you are a little confused with pointers. You appear to be calling "delete point" every time you are done using a pointer. This is not correct. You only want to call "delete point" when you want the memory that point points to to be released.


In List::add()
Node* point = head;
while (point->next)
    point = point->next;
point->next = new Node(data);
delete point;

The following code finds the tail of the list then adds a new item correctly as the new tail of the list, but then you delete the previous tail of the list, by calling delete point. After this the element in the list before the old tail still points to tail but now since you deleted it its memory is invalid and the list is broken. Once it is deleted the program is free to use the memory for any purpose. So if you then traverse your list to the deleted node its anyones guess what you will find as the data, and what node->next will point to..

John
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 1

Expert Comment

by:jdrescher
ID: 7008768
I think you are a little confused with pointers. You appear to be calling "delete point" every time you are done using a pointer. This is not correct. You only want to call "delete point" when you want the memory that point points to to be released.


In List::add()
Node* point = head;
while (point->next)
    point = point->next;
point->next = new Node(data);
delete point;

The following code finds the tail of the list then adds a new item correctly as the new tail of the list, but then you delete the previous tail of the list, by calling delete point. After this the element in the list before the old tail still points to tail but now since you deleted it its memory is invalid and the list is broken. Once it is deleted the program is free to use the memory for any purpose. So if you then traverse your list to the deleted node its anyones guess what you will find as the data, and what node->next will point to..

John
0
 

Author Comment

by:grfik
ID: 7009365
john u suggested that i do this:
if ( point == head ) {
// head node!
}
else
if ( point->next == NULL )
{
// Tail node
}
else
{
// Interior node!
}

and i am a little confused about pointers.. still a student
how would i implement wat you said?.. the text i am using isn't of much help and my professors expect too much and teach too little
0
 

Author Comment

by:grfik
ID: 7009366
do you know why the last line from the input file is saved in memory twice like i said earlier?
0
 

Author Comment

by:grfik
ID: 7009398
umm i tried to use some of u'r suggestions in my code and it worked very well.. the remove function is working almost perfectly now... only problem i get is as i stated earliar about the last fraction being loaded into memory twice..
and when i try to remove it from the list the program crashes, i dont know if it is because it is the last node or because of a problem inputing the problem

this is the part of the remove() function i changed

   if (point == head)
   {
      head = head->next;
      delete point;

   }
   else
   {
      Node* temp = point->next;
      point->next = temp->next;
      delete temp;
   }

i dont know how to delete the last node in a list, i thought that the code that works for removing the interior nodes would work for the last node as well.. atleast according to the text i am using..

i also removed the delete statements like you said.
0
 

Author Comment

by:grfik
ID: 7009873
umm i fixed the problem of the last fraction being loaded twice by changing the code in readFile() to
   while(inputFile)
   {
      inputFile >> data;
      if(inputFile.eof())
         break;

      point = head;
      while (point->next)
         point = point->next;
      point->next = new Node(data);

   }
the loop is broke before the extra data is put into a node..

now the only problem i have left is removing the last node..
program crashes if i try to
0
 

Author Comment

by:grfik
ID: 7009952
umm i was able to fix the program by fix the remove() function .. it looks like this if u'r interested

   if (point == head)
   {
      head = head->next;
   }

   point = head;

   for(int i = 0; i < position - 1; i++)
      point = point->next;

   if (!point->next)
   {
      Node* temp = point;
      delete temp;
   }
   else
   {
      Node* temp = point->next;
      point->next = temp->next;
      delete temp;
   }

i tested it and it all seemed to go well
drescher u'r comments helped most
0
 
LVL 1

Expert Comment

by:jdrescher
ID: 7009959
I think you are a little confused with pointers. You appear to be calling "delete point" every time you are done using a pointer. This is not correct. You only want to call "delete point" when you want the memory that point points to to be released.


In List::add()
Node* point = head;
while (point->next)
    point = point->next;
point->next = new Node(data);
delete point;

The following code finds the tail of the list then adds a new item correctly as the new tail of the list, but then you delete the previous tail of the list, by calling delete point. After this the element in the list before the old tail still points to tail but now since you deleted it its memory is invalid and the list is broken. Once it is deleted the program is free to use the memory for any purpose. So if you then traverse your list to the deleted node its anyones guess what you will find as the data, and what node->next will point to..

John
0
 
LVL 1

Expert Comment

by:jdrescher
ID: 7009966
Sorry about not being around today for help. Do you have anymore questions or is everything finished?
0
 

Author Comment

by:grfik
ID: 7010120
umm your comments lead me into the right direction and a few hours later and after trying several different things i finally got it..
i'm pretty confident that everything is finished and finished correctly..
thx for the help
0
 
LVL 1

Expert Comment

by:jdrescher
ID: 7013964
> your comments lead me into the right direction
Good. That is what I was trying to do, without providing the answer. EE is very picky about not allowing us to do some ones hwk but we are permitted to help..
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now