Это код, я создал класс, который содержит объект другого класса. Я получаю неправильный вывод, то есть значение мусора. Я не могу понять, в чем проблема.
Выделенная строка, вывод s дает значение для мусора, но в компиляции нет ошибки. Ive использовал MS Visual Studio 2010
#include<iostream>
#include<conio.h>
#include<string>
#include<cstring>
using namespace std;
class Address
{
char *street_no,*house_no,*city,*code;
public:
**Address(Address &obj)
{
int size;
cout<<obj.street_no;
size=strlen(obj.street_no);
street_no=new char[size+1];
strcpy(street_no,obj.street_no);
size=strlen(obj.house_no);
house_no=new char[size+1];
strcpy(house_no,obj.house_no);
size=strlen(obj.city);
city=new char[size+1];
strcpy(city,obj.city);
size=strlen(obj.code);
code=new char[size+1];
strcpy(code,obj.code);
}**
Address()
{
street_no=new char;
house_no=new char;
city=new char;
code=new char;
}
~Address()
{
delete street_no;
delete house_no;
delete city;
delete code;
}
void set()
{
cout<<"Enter Street Number : ";
cin>>street_no;
cout<<"Enter House Number : ";
cin>>house_no;
cout<<"Enter City : ";
cin>>city;
cout<<"Enter Code : ";
cin>>code;
}
void get()
{
cout<<"\nStreet Number : "<<street_no;
cout<<"\nHouse Number : "<<house_no;
cout<<"\nCity : "<<city;
cout<<"\nCode : "<<code;
}
};
class person
{
Address obj;
public:
person()
{
}
person(person &one)
{
Address::Address(one.obj);
}
void set()
{
obj.set();
}
void get()
{
obj.get();
}
~person()
{
exit(0);
}
};
int main()
{
person A;
A.set();
A.get();
**
person B(A);
B.get();
**
getch();
}
Address()
{
street_no=new char;
house_no=new char;
city=new char;
code=new char;
}
Здесь начинается ваша первая проблема. Когда вы используете конструктор по умолчанию, вы создаете указатели на один char
. Когда вы пытаетесь скопировать объект, вы получите мусор, так как strlen
будет искать символ \0
для определения длины (и если ваш char
просто "\ 0", вы собираетесь уйти в сорняки UB). Это также будет иметь место с вашими функциями get
и set
поскольку они пытаются выписать char*
(но на самом деле ожидают массив с завершающим нулевым символом) и читать в char*
(такое же ожидание), но вы только давая им 1 символ для записи. Другими словами, вы собираетесь вызывать UB повсюду с тем, что вы написали.
~Address()
{
delete street_no;
delete house_no;
delete city;
delete code;
}
Это будет отлично работать для вашего конструктора по умолчанию (как написано), но не будет корректным для вашего конструктора-копии. Как только вы исправите свой конструктор по умолчанию, это будет неверно для обоих. Когда вы создаете новый массив (new[]
), вы должны освободить память с помощью delete[]
.
Вся эта проблема может быть исправлена с помощью std::string
вместо того, чтобы пытаться самостоятельно управлять динамическими массивами.
В C++ используйте класс 'string' вместо char *. Тогда вам не нужно управлять памятью. Поэтому замените
char *street_no,*house_no,*city,*code;
с строкой street_no, house_no, city, code;
new char
изset
функции. Измените ваш конструктор, чтобы взять в качестве параметров street_no, house_no, city, code. Вы действительно не должны делать ввод-вывод из конструктора.