Dynamiczny przydział pamięci w klasie

0

**
class.h**

 #ifndef class_h_ 
#define class_h_ 
#include <iostream> 
#include <string.h> 
using std::cout; 
using std::endl; 
class Cow {
private:
char name[20];
char hobby;
double weight;
public:
Cow();
Cow(const char nm, const char*ho, double wt);
Cow(const Cow &c);
~Cow();
Cow & operator=(const Cow & c);
void ShowCow() const;
};
#endif // !classh

** def.cpp**

#include "class.h"

Cow::Cow()
{ 
    name[0] = '\0'; 
    hobby = new char[1];
    hobby[0] = '\0';
    weight = 0;
}

Cow::Cow(const char* nm, const char*ho, double wt)
{
    int len_h = strlen(ho);
    int len_n = strlen(nm);
    hobby = new char(len_h + 1);
    strcpy_s(name, len_n +1,nm);
    strcpy_s(hobby,len_h+1 ,ho);
    weight = wt;
}
Cow::~Cow()
{
    delete[] hobby; 
}
Cow::Cow(const Cow &c) // konstruktor kopiujący
{
    int len_h = strlen(c.hobby);
    int len_n = strlen(c.name);
    hobby = new char[len_h + 1];
    strcpy_s(hobby, len_h+1, c.hobby);
    strcpy_s(name, len_n+1, c.name);
    weight = c.weight;
}

Cow& Cow::operator=(const Cow & c) // celem operacji jest obiekt na rzecz którego wywołujemy metode ( jest on po lewej)
{
    if (this == &c)
        return *this;
    delete[] hobby; // obiekt docelowy może być zajęty więc zwalniamy 
    int len_h = strlen(c.hobby);
    hobby = new char[len_h + 1];
    strcpy_s(hobby,len_h+1 ,c.hobby);
    int len_n = strlen(c.name);
    strcpy_s(name, len_n+1 , c.name);
    weight = c.weight;
    return *this; // zwracamy obiekt na rzecz którego wywoływano metode
}

void Cow::ShowCow() const
{
    cout << name<<endl;
    cout << hobby << endl;
    cout << weight << endl;
}

main.cpp

#include "class.h"

int main()
{
Cow krowa0;
Cow krowa1 = Cow("jan", "trawa", 2);
krowa1.ShowCow();
system("pause");
return 0;
}

Hejka, mam problem z głębokim kopiowaniem :( Wywala mi błąd: "CRT detected that the application wrote to memory after end of heap buffer" szukałem, ale nie doszukałem się błędu(może problem leży w strcpy_s ??). Dokładnie problem leży w składowej hobby, gdy nie próbuje jej wyświetlić wszystko działa jak należy.
Dziękuje za pomoc ;)

4

char hobby; to jest znak, a nie wskaźnik na znak/tablicę znaków. Ale w tym momencie hobby[0] = '\0'; nie powinno się skompilować, na pewno podajesz poprawny kod?

W operatorze przypisania:
hobby = new char(len_h + 1); alokujesz jeden znak o wartości len_h + 1, a nie tablicę znaków. () i [] robi różnicę. Ponadto nigdzie nie usuwasz poprzedniego stringa, więc masz wyciek pamięci.

0

To co podałeś nie kompiluje się: https://ideone.com/U7Wk1J

0
kq napisał(a):

char hobby; to jest znak, a nie wskaźnik na znak/tablicę znaków. Ale w tym momencie hobby[0] = '\0'; nie powinno się skompilować, na pewno podajesz poprawny kod?

W operatorze przypisania:
hobby = new char(len_h + 1); alokujesz jeden znak o wartości len_h + 1, a nie tablicę znaków. () i [] robi różnicę. Ponadto nigdzie nie usuwasz poprzedniego stringa, więc masz wyciek pamięci.

Oczywiście mój błąd:

  1. char * hobby powinno być źle skopiowałem
  2. Oczywiście zamiast new char[len_h+1] dałem new char(len_h+1) z głupiego przeoczenia ;)
    Dziękuje bardzo
2

nie znoszę nieuzasadnionej mieszanki C++ i C.
Jakbyś porzucił C to nie było by problemów.

class Cow {
private:
    string name;
    string hobby;
    double weight;
public:
    Cow();
    Cow(const string& nm, const string& ho, double wt);
    // niepotrzebne domyślny działa: Cow(const Cow &c) = ;
    // niepotrzebne domyślny działa: ~Cow();
    // niepotrzebne domyślny działa: Cow & operator=(const Cow & c);
    void ShowCow() const;
};

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