Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Dynamiczne zarządzanie pamięcią (new, delete) - metoda dodajaca nowy punkt do tablicy

Ostatnio zmodyfikowano 2016-01-03 17:14
Autor Wiadomość
szarry
Temat założony przez niniejszego użytkownika
Dynamiczne zarządzanie pamięcią (new, delete) - metoda dodajaca nowy punkt do tablicy
» 2016-01-02 17:26:37
Witam serdecznie w nowym roku!
Piszę część aplikację, której zadanie polegać będzie na odczytywaniu z rejestratora danych o warunkach środowiskowych (temperatura, wilgotność, ciśnienie) i prezentowaniu wyników w postaci wykresu tych wartości w czasie.
Mam problem z następującym kawałkiem kodu:
C/C++
class Punkt {
public:
    unsigned int punktLp;
    float punktWartosc;
    unsigned int punktCzasWzgl;
};

class Seria {
public:
    ~Seria();
   
    std::string nazwaSerii;
   
    Punkt * pomiary;
    unsigned int pomiaryIlosc;
   
    float wartoscMax();
    float wartoscMin();
    float wartoscSrednia();
   
    int wczytajPlik( std::string nazwaPlikuDoOdczytu );
    int zapiszPlik( std::string nazwaPlikuDoZapisu );
   
private:
    std::ifstream plikOdczyt;
    std::ofstream plikZapis;
    bool dodanoPunkt;
   
    unsigned int pomiaryMaxLp;
    unsigned int pomiaryMinLp;
    float pomiarySrednia;
   
    void odswiezSredniaMinMax() {
        obliczSrednia();
        znajdzLpMax();
        znajdzLpMin();
    }
   
    int dodajPunkt( Punkt punktDoDodania );
    void obliczSrednia();
    void znajdzLpMax();
    void znajdzLpMin();
};

//[...]

int Seria::dodajPunkt( Punkt punktDoDodania ) {
    Punkt * pomiaryNowe;
    pomiaryNowe = new Punkt[( pomiaryIlosc + 1 ) ];
    for( unsigned int i = 0; i < pomiaryIlosc; i++ ) {
        pomiaryNowe[ i ].punktLp = pomiary[ i ].punktLp;
        pomiaryNowe[ i ].punktCzasWzgl = pomiary[ i ].punktCzasWzgl;
        pomiaryNowe[ i ].punktWartosc = pomiary[ i ].punktWartosc;
    }
    pomiaryNowe[ pomiaryIlosc ].punktLp = punktDoDodania.punktLp;
    pomiaryNowe[ pomiaryIlosc ].punktCzasWzgl = punktDoDodania.punktCzasWzgl;
    pomiaryNowe[ pomiaryIlosc ].punktWartosc = punktDoDodania.punktWartosc;
    pomiaryIlosc++;
   
    delete pomiary;
    pomiary = &* pomiaryNowe;
    dodanoPunkt = true;
    return dodajPunktSukces;
}

Debugger wysypuje się przy instrukcji delete pomiary z komunikatem o niepoprawnym wskaźniku. Podejrzewam, że jak zwykle pogubiłem się z * i &.
P-142709
mateczek
» 2016-01-02 17:58:01
a gdzie rezerwacja pamięci dla pomiary ?? nie możesz użyć "delete" gdy nie użyłeś "new"
C/C++
delete pomiary;
pomiary = pomiaryNowe; // tu chyba normalnie przypisanie wskaźników

// no chyba że chciałeś

class Seria {
public:
    ~Seria();
   
    std::string nazwaSerii;
   
    Punkt * pomiary = NULL;
    //    [....]
    if( pomiary != NULL ) delete pomiary // nie wolno Ci użyć delete na wskaźniku który na nic nie pokazuje!!!
P-142713
j23
» 2016-01-02 18:20:46
@mateczek, jeśli wskaźnik jest nullptr, wtedy delete nic nie robi.

PS. dla tablic powinno być delete[] pomiary;


@szarry. realokowanie tablicy co każdy nowy punkt nie jest zbyt dobrym rozwiązaniem. Alokować większymi partiami i ewentualnie użyć placement new. A najlepiej użyć std::vector
P-142714
szarry
Temat założony przez niniejszego użytkownika
Odkryłem wektroy :)
» 2016-01-03 17:14:06
Dziękuję pięknie za sugestię o wektorach (coś kiedyś mi się o uszy obiło, ale potem o tym zapomniałem). Bardzo wygodne i użyteczne narzędzie.
Problem rozwiązany, program działa.
Wrzucam działający kod, jakby ktoś szukał w przyszłości:
C/C++
std::vector < Punkt > pomiary;
//[...]

int Seria::dodajPunkt( Punkt punktDoDodania ) {
    pomiary.push_back( punktDoDodania );
    pomiaryIlosc = pomiary.size(); //z powodzeniem mozna uzywac metody .size() w warunkach np. petli for.
    //zabieg ten zastosowalem bo uzywam pomiaryIlosc w wielu miejscach i udostepniam jako element interfejsu klasy.
    dodanoPunkt = true;
    return dodajPunktSukces;
}

Na koniec złota myśl:
Jak się kopiuje projekt z Linuksa do Windowsa, to warto użyć Rebuild all. Komunikatu żadnego nie dostałem, a spędziłem dobre dwie godziny na szukaniu błędu w kodzie :)
P-142777
« 1 »
  Strona 1 z 1