Problem z dynamiczną alokacją pamięci (chyba)

0

Witam, mam problem z dynamiczną alokacją pamięci (tak przypuszczam :-) ).
Program się kompiluje, ale niepoprawnie wyświetla dane, będące składnikami klasy (char *), które są właśnie alokowane dynamicznie. Piszę w dev'ie 4.9.9.2. Działa dobrze, jeśli zamiast tablicy obiektów tworzonej operatorem new definiujemy zmienną automatyczną. Ale ja potrzebuję dynamicznej tablicy obiektów.
Kod skróciłem do niezbędnego minimum. Ktoś ma jakiś pomysł? Bo ja już cały dzień się z tym męczę i nie mogę dojść co jest z tym kodem nie tak.

#include <iostream>
using namespace std;

class Osoba {
    public:
    char * nazwisko;
    char * imie;
    Osoba(char * n, char * iw);
    ~Osoba();
};

Osoba::Osoba(char * n = "", char * i = "")
{
    nazwisko = new char[strlen(n) + 1];
    strcpy(nazwisko, n);
    imie = new char[strlen(i) + 1];
    strcpy(imie, i);
    cout << "Konstruktor: "
         << imie << " "
         << nazwisko << endl;
}

Osoba::~Osoba()
{
    cout << "Destruktor\n";
    delete [] nazwisko;
    delete [] imie;
}

int main()
{
    Osoba * o;
    o = new Osoba[1];
    o[0] = Osoba("Kowalski", "Jan");
    cout << o[0].nazwisko << endl;
    cout << o[0].imie << endl;
    delete [] o;
    return 0;
}

Z góry dzięki za wszelką pomoc.

0

Trzeba zdefiniować w klasie Osoba konstruktor kopiujący i operator przypisania.

0

Oczywiście że nie działa! Nie wiem czy ty wiesz co ty tam wyprawiasz. Możesz zrobic tak:

Osoba* o = new Osoba("Kowalski", "Jan");
cout << o[0].nazwisko << endl;
cout << o[0].imie << endl;
delete o;

I będzie ok. Twój błąd polega na tym że:

o = new Osoba[1]; //tworzysz tablicę obiektów -> tworzysz te obiekty, one już są stworzone!
o[0] = Osoba("Kowalski", "Jan"); //tworzysz nowy obiekt lokalny i przypisujesz sobie te obiekty, jako ze nie zdefiniowałes operatora= i konstruktora kopiującego to zrobi ci kopiowanie pole po polu, wiec przypisze wskaźniki do siebie, ale obiekt lokalny zaraz zniknie i te wskaźniki będą martwe, skasowanie tego obiektu drugi raz spowoduje podwójne delete na tych wskaźnikach i błąd.

Jeśli chcesz tak operować na tablicy to musisz zrobic metodę która ustawi wartości pól dla obiektu na przykład. Albo zdefiniowac operator= i kontruktor kopiujacy

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

class Osoba
{
    public:
    char* nazwisko;
    char* imie;
    Osoba(const char* n,const char* iw);
    Osoba(const Osoba& wzor); //konstruktor kopiujacy
    Osoba& operator=(const Osoba& wzor);
    void setIM(const char* n,const char* i);
    ~Osoba();
};

Osoba::Osoba(const char * n = "",const char * i = "")
{
    nazwisko = new char[strlen(n) + 1];
    strcpy(nazwisko, n);
    imie = new char[strlen(i) + 1];
    strcpy(imie, i);
    cout << "Konstruktor: "
         << imie << " "
         << nazwisko << endl;
}

Osoba::Osoba(const Osoba& wzor)
{
    nazwisko = new char[strlen(wzor.nazwisko) + 1];
    strcpy(nazwisko, wzor.nazwisko);
    imie = new char[strlen(wzor.imie) + 1];
    strcpy(imie, wzor.imie);
}

Osoba& Osoba::operator=(const Osoba& wzor)
{
    if(&wzor != this)
    {
      delete[] nazwisko;
      delete[] imie;
      nazwisko = new char[strlen(wzor.nazwisko) + 1];
      strcpy(nazwisko, wzor.nazwisko);
      imie = new char[strlen(wzor.imie) + 1];
      strcpy(imie, wzor.imie);
    }
  return *this;
}

void Osoba::setIM(const char* n,const char* i)
{
    delete[] nazwisko;
    delete[] imie;
    nazwisko = new char[strlen(n) + 1];
    strcpy(nazwisko, n);
    imie = new char[strlen(i) + 1];
    strcpy(imie, i);
}

Osoba::~Osoba()
{
    cout << "Destruktor\n";
    delete [] nazwisko;
    delete [] imie;
}

int main()
{
    Osoba* o = new Osoba[1];
    //o[0].setIM("Kowalski","Jan"); //można tak
    o[0] = Osoba("Kowalski","Jan"); //albo tak
    cout << o[0].nazwisko << endl;
    cout << o[0].imie << endl;
    delete o;
    return 0;
}

0

Wielkie dzięki za pomoc. Jak zwykle rozwiązanie okazało się banalne. Wystarczyło wyłączyć komputer na kilka godzin i wszystko stało się jasne.
W każdym razie dzięki za cenne wskazówki.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.