Welcome!
I have a problem with use of destructor in my program. If I am using delete *char in destructor, something strange is going on, I mean program doesn't work properly (the line with the code is signed by arrow). There is everything alright when I remove this line, but I am worried about memory leaking in this case.
Also I have some problem with 20th line - i have no idea how to do this, but it works in gcc.
Additionally, if you have seen any mistake or you have any advice for me, you are kindly requested to write it :)
Thank for your answers in advance!
#include <iostream>
#include <string.h>
usingnamespace std;
class MyClass
{
public:
//MyClass();
struct element
{
char* sign;
int number;
struct element *pnext;
};
element *head = new element; // warning - non-static data members
//initializers only available with -std=c++11 or -std=gnu++11
MyClass () //constructor definition
{
head = NULL;
};
virtual ~MyClass () //destructor
{
element *tmp;
while (head) {
tmp = head;
delete head->sign;
head = head->pnext;
//delete tmp->sign; //<<-------------- here is the problem
delete tmp;
}
}
void insertElement(char*, int number); //insert element to the list with alphabetical order
void removeElement(char*); //remove element from the list with any given string
void print();
int & value (char *);
};
MyClass ob;
/*There is inefficiency in insertElement in the value function. It search the char from the beginning from the beginning.*/
int main()
{
// int na = 5;
ob.print();
int i=ob.value((char*) "tata");
cout << i << endl;
ob.value("tata")=3;
cout << ob.value((char*)"tata") << endl;
ob.value((char*)"mama")=18;
ob.value((char*)"babcia")=5;
ob.value((char*)"tata")=24;
ob.value((char*)"amam")=9;
ob.value((char*)"tata")=10;
ob.print();
ob.value("tesciowa")=3;
ob.value("tesciowa")=13;
i=ob.value("tesciowa");
cout << i <<endl;
ob.print();
ob.value("komputer")=7;
ob.print();
//delete ob.head;
return 0;
}
void MyClass::insertElement(char* szstr, int na)
{
element *temp=new element;
temp->sign = newchar(strlen(szstr)+1);
//element *temp2=new element; //previous element
element *p = head;
element *temp2= head; //if the head is the first element, there will be situation that temp2 will be prev.
cout << "You want to add element with char ' " << szstr << " ' and number " << na << "." << endl;
temp->sign = szstr;
temp->number = na;
temp->pnext = NULL;
if (head == 0) // The first element of the list; if any does not exist
{
head=temp;
return;
}
else
{
while (p)
{
if (strcoll(temp->sign, p->sign) < 1)
{
if (p==head)
{
head=temp;
head->pnext=temp2;
break;
}
else
{
temp2->pnext=temp;
temp->pnext=p;
break;
}
}
else
{
if(p->pnext==NULL)
{
//temp->pnext=NULL;
p->pnext=temp;
break;
}
temp2=p;
p=p->pnext;
}
}
}
}
void MyClass::removeElement (char* pa)
{
element *temp = head;
element *prev = head;
while (temp!=NULL)
{
if (strcoll(pa, temp->sign) == 0)
if (temp==MyClass::head) //if this is the first element
{
MyClass::head=MyClass::head->pnext;
delete temp;
cout << "element has been removed." << endl;
return;
}
else //if it is not the first
{
prev->pnext = temp->pnext;
delete temp;
cout << "The element has been removed" << endl;
temp = prev->pnext;
return;
}
else
{
prev = temp;
temp = temp -> pnext;
}
};
cout << "There is nothing to remove!" << endl;
}
void MyClass::print()
{
//element *ptr= new element;
//ptr=head;
element *ptr(head);
short ncon(1);
if (ptr == NULL)
cout << "The list is empty." << endl;
else
{
while (ptr!=NULL)
{
cout << ncon << ". ch: " << ptr->sign << ", int: " << ptr->number << endl;
ncon++;
ptr=ptr->pnext;
}
}
//delete ptr;
}
int &MyClass::value (char* pa)
{
element *temp = head;
//element *prev = head;
while (temp!=NULL) //if there exist the string in the list
{
if (strcoll(pa, temp->sign) == 0)
{
return temp->number;
}
else
{
temp=temp->pnext;
}
}
int ndef(10); //default number to add with new element
insertElement(pa, ndef);
return value((char*)pa);
}
Thanks for the answer.
Unfortunately I must not use std::string because of supervisor's directions. I must use char* instead.
I improved my code a little, but there is still the same result of running - some strange signs. I also don't understand why there is a leak in temp->sign = szstr; - could you explain it for me in some simple few words?
There is the new code:
#include <iostream>
#include <string.h>
usingnamespace std;
class MyClass
{
public:
struct element
{
char* sign;
int number;
struct element *pnext;
};
element *head;
char *id;
MyClass (char*);
~MyClass ();
void insertElement(char*, int number); //insert element to the list with alphabetical order
void removeElement(char*); //remove element from the list with any given string
void print();
int & value (char *);
};
/*There is inefficiency in insertElement in the value function. It search the char from the beginning from the beginning.*/
int main()
{
MyClass a="List a", b="List b";
a.print();
int i=a.value((char*) "tata");
cout << i << endl;
a.value("tata")=3;
cout << a.value((char*)"tata") << endl;
a.value((char*)"mama")=18;
a.value((char*)"babcia")=5;
a.value((char*)"tata")=24;
a.value((char*)"amam")=9;
a.value((char*)"tata")=10;
a.print();
a.value("tesciowa")=3;
a.value("tesciowa")=13;
i=a.value("tesciowa");
cout << i <<endl;
a.print();
a.value("komputer")=7;
a.print();
return 0;
}
MyClass::MyClass (char *sname) //constructor definition
{
head = NULL;
id = newchar (strlen(sname+1));
strcpy(id,sname);
cout << "Element with the ID " << id << " has been created." << endl;
};
MyClass::~MyClass () //destructor
{
element *tmp;
cout << "Element " << id << " destroyed.";
delete id;
while (head)
{
tmp = head;
head = head->pnext;
//delete tmp->sign; //<<-------------- error
delete tmp;
}
}
void MyClass::insertElement(char* szstr, int na)
{
element *temp=new element;
temp->sign = newchar(strlen(szstr)+1);
element *p = head;
element *temp2= head; //if the head is the first element, there will be situation that temp2 will be prev.
cout << "You want to add element with char ' " << szstr << " ' and number " << na << "." << endl;
temp->sign = szstr;
temp->number = na;
temp->pnext = NULL;
if (head == 0) // The first element of the list; if any does not exist
{
head=temp;
return;
}
else
{
while (p)
{
if (strcoll(temp->sign, p->sign) < 1)
{
if (p==head)
{
head=temp;
head->pnext=temp2;
break;
}
else
{
temp2->pnext=temp;
temp->pnext=p;
break;
}
}
else
{
if(p->pnext==NULL)
{
p->pnext=temp;
break;
}
temp2=p;
p=p->pnext;
}
}
}
}
void MyClass::removeElement (char* pa)
{
element *temp = head;
element *prev = head;
while (temp!=NULL)
{
if (strcoll(pa, temp->sign) == 0)
if (temp==MyClass::head) //if this is the first element
{
MyClass::head=MyClass::head->pnext;
delete temp;
cout << "element has been removed." << endl;
return;
}
else //if it is not the first
{
prev->pnext = temp->pnext;
delete temp;
cout << "The element has been removed" << endl;
temp = prev->pnext;
return;
}
else
{
prev = temp;
temp = temp -> pnext;
}
};
cout << "There is nothing to remove!" << endl;
}
void MyClass::print()
{
element *ptr(head);
short ncon(1);
if (ptr == NULL)
cout << "The list is empty." << endl;
else
{
while (ptr!=NULL)
{
cout << ncon << ". ch: " << ptr->sign << ", int: " << ptr->number << endl;
ncon++;
ptr=ptr->pnext;
}
}
}
int &MyClass::value (char* pa)
{
element *temp = head;
while (temp!=NULL) //if there exist the string in the list
{
if (strcoll(pa, temp->sign) == 0)
{
return temp->number;
}
else
{
temp=temp->pnext;
}
}
int ndef(10); //default number to add with new element
insertElement(pa, ndef);
return value((char*)pa);
}
> I must not use std::string because of supervisor's directions. I must use char* instead.
Still, encapsulate that `char *' in a class of your own.
> I also don't understand why there is a leak in temp->sign = szstr;
Because you simply overwrite the value that `new' give you. temp->sign = szstr; does not copy the content of the string (use strcpy() for that), but simply copies the pointer