-2
#include <iostream>
#include <string.h>
using namespace std;


class Location
{
double lat, lon;
char *emi;

public:
Location(int =0, int=0, const char* =NULL);
~Location();
Location (const Location&);
void print () const;
friend ostream& operator<< (ostream&, const Location &);
void operator! ();


protected: ;

private:
};

Location::Location(int lat, int lon, const char *emi) 
{
this->lat=lat;
this->lon=lon;
if (emi!=NULL)
{
this->emi=new char [strlen (emi)+1];
strcpy (this->emi, emi);
}

}

Location::~Location()
{
if (emi!=NULL)
delete []emi;

}

Location::Location(const Location &l)
{
lat=l.lat;
lon=l.lon;
if (l.emi!=NULL)
{
emi=new char [strlen (l.emi)+1];
strcpy (emi, l.emi);
}
}
void Location::operator! ()
{
if (!(strcmp(this->emi, "north")))
strcpy (this->emi, "south");
else strcpy (this->emi, "north");
}


void Location::print() const
{
cout<<this->emi<<endl;
cout<<this->lon<<endl;
cout<<this->lat<<endl;
cout<<endl;
}
class Adress
{
char *des;
Location l1;
char *country;
public:
Adress(char *,const Location &, char *);
virtual ~Adress();
friend ostream& operator<< (ostream&, const Adress &);



protected:

private:
};


Adress::Adress(char *des,const  Location &l1, char *country)
{
if (des!=NULL)
{
this->des=new char [strlen (des)+1];
strcpy (this->des, des);
}
if (country!=NULL)
{
this->country=new char [strlen (country)+1];
strcpy (this->country, country);
}
this->l1=l1;
}

Adress::~Adress()
{
if (country!=NULL)
delete []country;
if (des!=NULL)
delete []des;
}
ostream& operator<< (ostream &os, const Adress& a){
os <<"Descrition: " << a.des<<endl;
os<<"Country: "<<a.country<<endl;
a.l1.print();
return os;
}

int main ()
{
Adress a1 ("dsad", Location (323, 34, "fdsf"), "fsdf");
cout<<a1;
}

The problem is that when I create an Adress object and display it, all the fields are correct , but the "emi" which is messed up, showing a random character. I think the destructor is called before I display it. If I remove the Location destructor it works. How should I resolve it? I'm sorry for my mistakes but I am a newbie.

Robert1428
  • 33
  • 8
  • 2
    Please edit your question to contain [mcve] – Slava Apr 24 '18 at 15:59
  • 3
    Please post real code, this does not compile even after adding the missing parts – Jabberwocky Apr 24 '18 at 15:59
  • 2
    You haven't written the `operator=` for `Location` is that on purpose? This will use the default implementation which simply copies the pointer. This pointer points to something that is delete when the original instance leaves scope. – Tommy Andersen Apr 24 '18 at 16:00
  • That's obviously not code you've actually compiled and tested yourself. Please [edit] to fix the errors; you should also include the necessary headers and `main()` function to make it a [mcve]. P.S. spelling: **Address** (two d's) – Toby Speight Apr 24 '18 at 16:01
  • 3
    Unrelated but why are you writing classes but not using `std::string`? – James Adkison Apr 24 '18 at 16:02
  • Possible duplicate of [C++ Copy Constructor + Pointer Object](https://stackoverflow.com/questions/3740471/c-copy-constructor-pointer-object) – underscore_d Apr 24 '18 at 16:03
  • @TommyAndersen I've written the copy constructor, should I write overload the assigment operator too? – Robert1428 Apr 24 '18 at 16:14
  • @Robert1428 you have written the copy constructor, but you are using the assignment operator, that is why you should write that too :) – Tommy Andersen Apr 24 '18 at 16:15

1 Answers1

2

First of all, it would be better to use std::string rather than char* but I will explain your problem for the education goal.

You must ensure after constructing an object, all of its member variables are initialized. In the case of Location class for example; you did not initialize the emi member variable if the third argument of the constructor is nullptr. so I changed it a little:

Location::Location(int _lat, int _lon, const char* _emi)
    : lat(_lat)
    , lon(_lon)
    , emi(nullptr)
{
    if (_emi != nullptr)
    {
        emi = new char[strlen(_emi) + 1];
        strcpy(emi, _emi);
    }
}

Next, you have a raw pointer in your class and you can not simply copy or assign it. You have to implement the assignment operator as well as the copy constructor.

Location& Location::operator=(const Location& other)
{
    if (this != &other)
    {
        lat = other.lat;
        lon = other.lon;
        if (emi) delete[] emi;
        emi = new char[strlen(other.emi) + 1];
        strcpy(emi, other.emi);
    }
    return *this;
}
wxShayan
  • 288
  • 1
  • 4
  • 12