Operator przypisania i dynamiczna alokacja char

0

Szanowni użytkownicy forum, mam problem w moim programie a mianowicie, gdy podaje rozmiar mniejszy niż jest dodawana liczba osób do tablicy program powinien tworzyć na nowo tablice większą aby kolejna osoba mogła zostać dodana a jednak wyskakuje błąd "segmentation fault" wiem, że ten błąd wyskakuje u operatora przypisania w linii: nazwisko = new char[strlen(wzor.nazwisko)+1];
Proszę o pomoc.

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


class osoba{
private:
	char *nazwisko;
	int wiek;
public:
	osoba(){
		nazwisko = new char[NULL];
	}
	osoba(char *nazwisko, int lata);
	osoba(osoba &wzorzec);
	osoba & operator=(const osoba &wzor);
	bool operator!=(const osoba &wzor);
	~osoba(){
		delete nazwisko;
	}
	void wypisz();
	friend class TabOsoba;
};
osoba::osoba(char *napis,int lata){
	nazwisko = new char[strlen(napis)+1];
	strcpy(nazwisko,napis);
	wiek=lata;
}
osoba::osoba(osoba &wzorzec){
	nazwisko = new char[strlen(wzorzec.nazwisko)+1];
	strcpy(nazwisko,wzorzec.nazwisko);
	wiek=wzorzec.wiek;
}
void osoba::wypisz(){
	cout<<nazwisko <<"\t" <<wiek <<endl;
}

osoba & osoba::operator=(const osoba &wzor){
	if(*this!=wzor){
		delete nazwisko;
		cout << "przed alokacja"<<endl;
		nazwisko = new char[strlen(wzor.nazwisko)+1];
		cout<< "po alokacji"<<endl;
		strcpy(nazwisko,wzor.nazwisko);
		wiek = wzor.wiek;
	}
	return *this;
}

bool osoba::operator!=(const osoba &wzor){
	if((wzor.nazwisko == nazwisko)&&(wzor.wiek == wiek)){
	return false;
	}
	else return true;
}

class TabOsoba {
	int rozmiar;
	int licznik;
	osoba *Tab;
public:
	TabOsoba();
	TabOsoba(int r);
	~TabOsoba();
	void DodajOsobe(char *n, int e);
	void DodajOsobe();
	void DodajOsobe(osoba &wzor);
	TabOsoba(TabOsoba &wzorzec);
	int PodajRozmiar(){
	return rozmiar;
	}
	void WypiszTablice();
	bool Szukaj(char *nazw, TabOsoba &Szuk);
};
TabOsoba::TabOsoba(){
	cout<<"podaj rozmiar: ";
	cin>> rozmiar;
	Tab = new osoba[rozmiar];
	licznik = 0;
}
TabOsoba::TabOsoba(int r){
	rozmiar = r;
	licznik= 0;
	Tab = new osoba[r];
}
TabOsoba::~TabOsoba(){
delete []Tab;
rozmiar = 0;
licznik = 0;
}
void TabOsoba::DodajOsobe(char *n, int e){
 if(licznik >= rozmiar){
	TabOsoba wzor;
	wzor = *this;
	delete []Tab;
	wzor.rozmiar += 1;
	osoba *Tab = new osoba[rozmiar];
	for(int i=0;i<rozmiar;i++)Tab[i]=wzor.Tab[i];
		}
	Tab[licznik] = osoba(n, e);
	licznik++;
}
void TabOsoba::DodajOsobe(){
	char *Nazwisko= new char[NULL];
	int Wiek;
	cout << "podaj nazwisko"<<endl;
	cin >> Nazwisko;
	cout << "podaj wiek"<< endl;
	cin >> Wiek;
	if(licznik >= rozmiar){
	 TabOsoba wzor;
	 wzor = *this;
	delete []Tab;
	rozmiar += 1;
	osoba *Tab = new osoba[rozmiar];
	for(int i=0;i<rozmiar;i++)Tab[i]=wzor.Tab[i];
	}
		Tab[licznik] = osoba(Nazwisko,Wiek);
		licznik++;
}

void TabOsoba::WypiszTablice(){
	for(int i = 0; i < licznik; i++){
		Tab[i].wypisz();
	}
}

void TabOsoba::DodajOsobe(osoba &wzor){
	if(licznik >=rozmiar){
	TabOsoba wzor;
	wzor = *this;
	delete []Tab;
	rozmiar += 1;
	osoba *Tab = new osoba[rozmiar];
	for(int i=0;i<rozmiar;i++)Tab[i]=wzor.Tab[i];
	}
	Tab[licznik] = osoba(wzor);
	licznik++;
}

TabOsoba::TabOsoba(TabOsoba &wzorzec){
	rozmiar=wzorzec.rozmiar;
	Tab=new osoba[rozmiar];
	licznik=wzorzec.licznik;
	for(int i=0;i<wzorzec.licznik;i++){
		Tab[i]=wzorzec.Tab[i];
	}
}

bool TabOsoba::Szukaj(char *nazw, TabOsoba &Szuk){
	bool a=0;
	for(int i = 0; i < licznik; i++){
		if((strcmp(Tab[i].nazwisko,nazw)) == 0){
			Szuk.DodajOsobe(Tab[i]);
			a++;
		}
	}
	return a;
}

int main()
{
	TabOsoba Student;
	Student.DodajOsobe("Kowalski", 20);
	Student.DodajOsobe("Milanowski", 15);
	Student.DodajOsobe("Nowak", 40);
	Student.DodajOsobe("Kowalski", 20);
	Student.DodajOsobe("Milanowski", 15);
	Student.PodajRozmiar();
	cout << "Aktualny rozmiar: " << Student.PodajRozmiar() << endl;
	TabOsoba Szuk;
	Student.Szukaj("Milanowski",Szuk);
	Szuk.WypiszTablice();
	return 0;
}
4
    char *Nazwisko= new char[NULL];
    int Wiek;
    cout << "podaj nazwisko"<<endl;
    cin >> Nazwisko;

jak myślisz, co tu się dzieje?

Ponadto, new[] musi być sparowany z delete[] a nie delete. Ale zamiast tego po prostu użyj jak człowiek std::string

1
    char *Nazwisko= new char[NULL];
    int Wiek;
    cout << "podaj nazwisko"<<endl;
    cin >> Nazwisko;

Tworzysz tablice na 0 elementów a próbujesz wczytać nazwisko. Czego się spodziewałeś?

0

no dobra tylko, że nie korzystam z DodajOsobe() korzystam z parametrowego DodajOsobe i niestety nie mogę użyć string w tym zadaniu, musze char, a swoją drogą, co moge wpisać zamiast NULL aby było poprawnie ?

1
  1. popraw formatowanie ( http://format.krzaq.cc )
  2. zmieniasz wzor.rozmiar, a potem korzystasz ze starej wartości this->rozmiar
  3. nie wymyślaj koła na nowo, użyj std::vector
1

No tam masz inny błąd. Robisz zmienna lokalna która zasłania pole klasy i do tego zupełnie źle "kopiujesz" dane przy powiększaniu tablicy. Generalnie ten kod to dramat...

0

Wszystko było w prządku dopóki był char nazwisko[30] dopiero po zmianie char na dynamiczne i dodanie operatora = oraz != sprawa się skomplikowała

1 użytkowników online, w tym zalogowanych: 0, gości: 1