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

Kasowanie dwuwymiarowej tablicy

Ostatnio zmodyfikowano 2016-12-23 17:31
Autor Wiadomość
KrulTibianus
Temat założony przez niniejszego użytkownika
Kasowanie dwuwymiarowej tablicy
» 2016-12-22 23:31:04
Cześć. Ćwiczę sobie tablice i coś mi nie pasuje przy kasowaniu dwuwymiarowej tablicy.


C/C++
int ** dwuwymiarowa( const int x, const int y ) //tworzenie tablicy
{
    int ** tablica = new int *[ x ];
    for( int i = 0; i < x; i++ )
    {
        tablica[ i ] = new int[ y ];
    }
    return tablica;
}

void wypelnijtablice( int * tab[], const int x, const int y ) //wypelnienie tablicy wartosciami
{
    for( int i = 0; i < x; i++ )
    for( int j = 0; j < y; j++ )
         tab[ i ][ j ] = i + j;
   
}


void wyswietldwuwymiarowa( int * tab[], const int x, const int y ) //wyswietlanie tablicy
{
    for( int i = 0; i < x; i++ )
    {
        for( int j = 0; j < y; j++ )
             cout << tab[ i ][ j ] << " ";
       
        cout << endl;
    }
}

void kasujtablice( int * tab[], const int x ) //kasowanie tablicy z pamieci
{
    for( int i = 0; i < x; ++i )
         delete[] tab[ i ];
   
    delete[] tab;
}


int main()
{
    const int A = 3, B = 4;
    int ** tab2d = dwuwymiarowa( A, B );
   
    wypelnijtablice( tab2d, A, B );
    wyswietldwuwymiarowa( tab2d, A, B );
   
    //cout << (int)tab2d << endl;
   
    kasujtablice( tab2d, A );
   
    //cout << (int)tab2d << endl;
   
    wyswietldwuwymiarowa( tab2d, A, B );
   
    return 0;
}

I tak. Tworzy tablice, wypełnia ją i wyświetla prawidłowo.
Wyświetlenie tablicy:
0 1 2 3
1 2 3 4
2 3 4 5
Po wywołaniu kasujtablice, tab2d dalej wskazuje poprzedni adres komórki (a chyba powinien być skasowany?) i po ponownym wywołaniu wyswietldwuwymiarowa mam następujące wyniki:
5036832 6039016 2 3
6039016 5036832 6029624 1883892058
2 3 4 5

Za każdym razem w pierwszym rzędzie 2 ostatnie elementy się nie kasują i wszystkie z ostatniego rzędu się nie kasują. Co ciekawe, elementy [2][1] i [1][2] mają taki sam adres jak tab2d.

Żeby było ciekawiej, na szybko dorobiłem zapis do pliku tych liczb i teraz przy takim wywołaniu
C/C++
kasujtablice( tab2d, A );
zapiszdopliku( tab2d, A, B );

//cout << (int)tab2d << endl;

wyswietldwuwymiarowa( tab2d, A, B );
Wyświetla mi takie wyniki:
7330592 7153128 7330072 7143620
7153128 7330592 7143736 1743907439
0 4000 557583681 62474

Elementy [2][1] i [1][2] dalej mają taki sam adres, co tab2d. Liczby 0 i 4000 są przy każdym uruchomieniu. Ale teraz przynajmniej tablica wydaje się wyczyszczona...

Czy tablica na pewno jest wyczyszczona? Jeśli tak, dlaczego nie czyści się do końca w przypadku bez zapisu do pliku?
P-155309
pekfos
» 2016-12-23 03:17:44
Po wywołaniu kasujtablice(), tab2d nie wskazuje na poprawny obszar pamięci.
P-155314
KrulTibianus
Temat założony przez niniejszego użytkownika
» 2016-12-23 14:11:05
Tak, to raczej oczywiste, że po skasowaniu nie powinno wskazywać poprawnego obszaru pamięci :P Tylko dlaczego po ponownym wywołaniu wyswietltablice, funkcja poprawnie wyświetla połowę elementów rzekomo skasowanej tablicy? Czy kasowały się wskaźniki na tablicę, a elementy tablicy pozostały nietknięte?

Chciałem to zdebugować, ale coś mi nie trybi debugger w codeblocks.
P-155325
mokrowski
» 2016-12-23 14:32:22
Większość systemów operacyjnych nie kasuje (czyli np. nie wypełnia zerem lub inną wartością) zwolnionej pamięci. Daje to większą wydajność (bo nie trzeba poświęcać czasu na kasowanie).
Jak to mówią "w C++ masz czasem nieszczęście że coś działa a nie powinno" :-)
P-155327
KrulTibianus
Temat założony przez niniejszego użytkownika
» 2016-12-23 16:59:17
Aha, hahaha :D Czyli rozumiem, że ten mój kod jest OK i nie mam co się doszukiwać błędów, tam gdzie ich nie ma?


@edit Dzięki Mokrowski, zamykam.
P-155339
mokrowski
» 2016-12-23 17:31:14
Masz potraktować dane w poprzednio zaalokowanej tablicy jako śmiecie. Śmiecie które przez przypadek, w tym systemie operacyjnym i w tym programie zawierały część danych poprzednich :-) Czyli nie powinieneś na tym bazować w programowaniu w żadnym razie.

Co do Twojego kodu, nie sprawdzałem. Dość że "śmieci nie są błędem".
P-155341
« 1 »
  Strona 1 z 1