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

[C++] Usuwanie czterowymiarowej tablicy

Ostatnio zmodyfikowano 2017-06-09 00:36
Autor Wiadomość
ArgonZapan
Temat założony przez niniejszego użytkownika
[C++] Usuwanie czterowymiarowej tablicy
» 2017-05-23 17:49:59
Tablica jest tworzona dynamicznie, lecz tylko jej pierwsze 2 indeksy, są zawsze wypełnione, pozostałe 2, są dynamicznie uzupełniane w trakcie działania programu, więc pod koniec działania obiektu, może być pusty.
Po stworzeniu, jej rozmiar wygląda tak

C/C++
Map[ NUMBER_OF_SECTORS ][ NUMBER_OF_SECTORS ][ SECTOR_SIZE ][ SECTOR_SIZE ]
Fragment destruktora:

C/C++
model::GameTile::~GameTile() {
    for( size_t i = 0; i < NUMBER_OF_SECTORS; i++ ) {
        for( size_t j = 0; j < SECTOR_SIZE; j++ ) {
            for( size_t k = 0; k < SECTOR_SIZE; k++ ) {
                delete[] Map[ i ][ j ][ k ];
            }
            delete[] Map[ i ][ j ];
        }
        delete[] Map[ i ];
    }
    delete[] Map;
}

W trakcie usuwania wyrzuca


Exception thrown at 0x00007FF6162312EF in Engine.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

Próbowałem przyrównać do nullptr, ale nie za bardzo to działa.
Jakieś sugestie ? :)
P-161477
pekfos
» 2017-05-23 18:05:51
Sprawdzaj czy wskaźniki nie są puste.
P-161479
ArgonZapan
Temat założony przez niniejszego użytkownika
» 2017-05-23 18:12:15
Próbowałem tak
C/C++
if( Map[ i ][ j ][ k ] != nullptr )
     delete[] Map[ i ][ j ][ k ];

Exception thrown at 0x00007FF7BF0912EF in Engine.exe: 0xC0000005: Access violation reading location 0x0000010000000001.

I dalej nic.
P-161480
pekfos
» 2017-05-24 00:19:21
Usuwanie pamięci akurat sobie poradzi z pustym wskaźnikiem.
P-161497
crash
» 2017-05-24 14:50:07
Po to jest STL, żeby z niego korzystać: std::vector<T>.

Jeśli T nie będzie ptr to sam zwolni pamięć wraz z końcem bloku kodu, ewentualnie for-range i delete

http://www.cplusplus.com/reference/vector/vector/

Wektor tak bardzo
P-161523
carlosmay
» 2017-05-25 10:10:18
Jeśli T nie będzie ptr to sam zwolni pamięć
Jeśli T będzie smart pointerem, to sam po sobie posprząta.
P-161558
Rashmistrz
» 2017-05-25 12:43:20
Panie, jak pan tą pamięć alokujesz przede wszystkim?
P-161563
ArgonZapan
Temat założony przez niniejszego użytkownika
» 2017-06-09 00:36:06
Inicjalizacja pierwszych 2 wymiarów, w konstruktorze.

C/C++
Map = new Tile ***[ NUMBER_OF_SECTORS ];
for( size_t i = 0; i < NUMBER_OF_SECTORS; i++ ) {
    Map[ i ] = new Tile **[ NUMBER_OF_SECTORS ];
    for( size_t j = 0; j < NUMBER_OF_SECTORS; j++ ) {
        Map[ i ][ j ] = nullptr;
    }
}


Tworzenie sektora, ale tylko jednego, kiedy zajdzie taka potrzeba.

C/C++
Map[ x ][ y ] = new Tile *[ SECTOR_SIZE ];
for( size_t i = 0; i < SECTOR_SIZE; i++ ) {
    Map[ x ][ y ][ i ] = new Tile[ SECTOR_SIZE ];
}

Nowy destruktor
C/C++
model::GameTile::~GameTile() {
    for( size_t i = 0; i < NUMBER_OF_SECTORS; i++ ) {
        for( size_t j = 0; j < NUMBER_OF_SECTORS; j++ ) {
            if( Map[ i ][ j ] != nullptr ) {
                for( size_t k = 0; k < SECTOR_SIZE; k++ ) {
                    if( Map[ i ][ j ][ k ] != nullptr )
                         delete[] Map[ i ][ j ][ k ];
                   
                }
               
            }
            delete[] Map[ i ][ j ];
        }
        delete[] Map[ i ];
    }
    delete[] Map;
}

Miejsce w którym psuje się program. Metoda ta rysuje kwadraty na ekranie, póki co.

C/C++
void GameView::drawTileSector( model::Tile ** tile ) {
    sf::Sprite field;
    field.setScale( scale );
    sf::Vector2f position;
    //field.setOrigin(TEXTURE_SIZE_X / 2, TEXTURE_SIZE_Y / 2);
    for( int i = 0; i < SECTOR_SIZE; i++ ) {
        for( int j = 0; j < SECTOR_SIZE; j++ ) {
            position = windowPostion - tile[ i ][ j ].position; // dokładnie tutaj
            if( position.x < 0 || position.y < 0 ) {
                continue;
            }
            position.x = position.x *( TEXTURE_SIZE_X * scale.x + 1 );
            if( position.x > 1920 ) continue;
           
            position.y = position.y *( TEXTURE_SIZE_Y * scale.y + 1 );
            if( position.y > 1080 ) continue;
           
            field.setPosition( position );
            field.setTexture( * tile[ i ][ j ].getTexture() );
            window->draw( field );
        }
    }
}


W przypadku gdy destruktor jest pusty, nic się nie psuje, wszystko działa jak powinno


Exception thrown: read access violation.

tile was 0xFFFFFFFFFFFFFFFF.
P-162278
« 1 »
  Strona 1 z 1