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

Dwuwymiarowa tablica dynamiczna

Ostatnio zmodyfikowano 2015-01-05 00:06
Autor Wiadomość
zzkk
Temat założony przez niniejszego użytkownika
Dwuwymiarowa tablica dynamiczna
» 2015-01-04 20:01:09
Wiem, że problem był często poruszany na tym forum, ale wydaje mi się, że mój jest nieco inny.
Mianowicie chcę stworzyć klasę "kredki", która będzie przechowywać wskaźniki na obiekty klasy o nazwie "kredka".

Na myśl przychodzi mi dwuwymiarowa tablica. Dodając do niej obiekty:
-chcę je posortować ze względu na kolor, czyli w przypadku tablicy dwuwymiarowej każdy wiersz mógłby "trzymać" kredki jednego koloru.
-kredki dodawane będą do bazy pojedynczo w trakcie działania programu
-w sumie będzie maksymalnie 10 kolorów i maksymalnie 4 kredki tego samego koloru.

Chciałam najpierw w konstruktorze skierować wszystkie wskaźniki tablicy na NULL, żeby móc wykryć czy dany wiersz koloru przy dodawaniu już istnieje (funkcja dodaj).

Trochę zawile może, ale kod wszystko wyjaśni:

C/C++
class kredki {
    int w;
    int k;
    kredka *** baza;
public:
    kredki();
    void dodaj( kredka * nowa );
    void oddaj();
    ~kredka();
};

kredki::kredki() {
    w = 10;
    k = 4;
   
    for( int i = 0; i < w; i++ ) {
        for( int j = 0; j < k; j++ )
             baza[ i ][ j ] = NULL;
       
    }
}

void kredki::dodaj( kredka * nowa ) {
    string kolor = nowa->kolor;
    int i, j;
    i = j = 0;
   
    //baza to macierz, w ktorej kazdy wiersz odpowiada innemu kolorowi kredki
   
    while( baza[ i ][ j ] and baza[ i ][ j ]->kolor != kolor ) { //szukamy wiersza z danym kolorem
        i++;
    }
   
    while( baza[ i ][ j ] ) j++; //jesli taki wiersz jest zapelniony
   
    baza[ i ][ j ] = nowa; //jesli nie to while sie nie wykona => j = 0
}

void kredki::oddaj() { //przy usuwaniu wlasciciela
    for( int i = 0; i < w; i++ )
    {
        if( !baza[ i ][ 0 ] ) break;
       
        for( int j = 0; j < k; j++ ) {
            if( !baza[ i ][ j ] ) break;
           
            baza[ i ][ j ]->wlasciciel = NULL;
            baza[ i ][ j ] = NULL;
        }
    }
}

kredki::~kredki() {
   
}


Problem jest taki, że program się zawiesza przy drugiej pętli 'for' konstruktora.
W czym tkwi i jak go rozwiązać?

Jestem otwarta na propozycje innej struktury, która spełniałaby swoje zadanie.
Dodam że listy odpadają, bo obiekty klasy kredka są wykorzystywane gdzie indziej jako lista (czyli nie można zmodyfikować next ponownie) i klasa kredki będzie tworzona dla każdego uzytkownika
P-124126
Monika90
» 2015-01-04 20:07:09

w sumie będzie maksymalnie 10 kolorów i maksymalnie 4 kredki tego samego koloru.
Skoro tak, to dlaczego w ogóle tablca dynamiczna? Wystarczy kredka* baza[10][4];

A błąd masz dlatego, że nie alokowałaś pamięci, kredka*** baza; to tylko wskaźnik, tablicę trzeba osobno alokować.
P-124131
zzkk
Temat założony przez niniejszego użytkownika
» 2015-01-04 20:12:37
nie alokowałam pamięci, bo jak stworzę nowe obiekty za pomocą "new kredka" i wskaźniki skieruję później na istniejące już obiekty kredka(taki mam zamiar) to będę miała wyciek pamięci bo zgubię gdzieś te "new kredka" (chyba, że się mylę).


jeśli stworzę kredka* tablica[10][4]; to będę mogła w niej przechowywać wskaźniki na obiekty kredka? bo już zgłupiałam ;D
P-124134
Monika90
» 2015-01-04 20:22:44
nie alokowałam pamięci, bo jak stworzę nowe obiekty za pomocą "new kredka" i wskaźniki skieruję później na istniejące już obiekty kredka(taki mam zamiar) to będę miała wyciek pamięci bo zgubię gdzieś te "new kredka" (chyba, że się mylę).
Bo chodzi nie oto by alokować obiekty klasy kredka, tylko miejsce na te wskażniki.


jeśli stworzę kredka* tablica[10][4]; to będę mogła w niej przechowywać wskaźniki na obiekty kredka? bo już zgłupiałam ;D
Tak.
P-124135
zzkk
Temat założony przez niniejszego użytkownika
» 2015-01-04 20:35:44
ok, dzięki.
Czyli trzymając się tej wersji z alokacją, w jaki sposób to zrobić jak nie przez new? W tej pętli np
C/C++
for( int i = 0; i < w; i++ ) {
    for( int j = 0; j < k; j++ )
         baza[ i ][ j ] = NULL;
   
P-124139
Monika90
» 2015-01-04 20:43:47
Czyli trzymając się tej wersji z alokacją,
Chodz Ci o wersję z kredka*** baza;? To jeset okropna wersja, ale jeżeli już musisz...
Więc trzeba alokować za pomocą new, ale nie pojedyńcze obiekty klasy kredka, tylko tablice wskażników:
C/C++
baza = new kredka **[ w ];
for( int i = 0; i < w; ++i )
     baza[ i ] = new kredka *[ k ];


i teraz możesz sobie wypełnić NULLami
C/C++
for( int i = 0; i < w; i++ ) {
    for( int j = 0; j < k; j++ )
         baza[ i ][ j ] = NULL;
   
P-124141
zzkk
Temat założony przez niniejszego użytkownika
» 2015-01-04 20:45:22
Wiem, że okropna, ale chyba mam masochistyczne zapędy w programowaniu :D
Dziękuję bardzo za pomoc :)
P-124142
zzkk
Temat założony przez niniejszego użytkownika
» 2015-01-04 21:20:19
i jeszcze ostatnia konsultacja. Destruktor wygląda tak?

C/C++
for( int i = 0; i < w; ++i )
     delete[] baza[ i ];

delete[] baza;
P-124148
« 1 » 2
  Strona 1 z 2 Następna strona