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

[C++][SFML] Wielkie miasto, wielkie budynki i wielkie tablice

Ostatnio zmodyfikowano 2012-06-19 15:11
Autor Wiadomość
Schulze13
Temat założony przez niniejszego użytkownika
[C++][SFML] Wielkie miasto, wielkie budynki i wielkie tablice
» 2012-06-17 13:19:45
Witam,
Od pewnego czasu piszę City Buildera i właśnie się natknąłem na następujący problem: Budynki są budowane losowo  na wyznaczonych strefach. Jak wiadomo drapacz chmur z trudem zajmie pole o wielkości 10 na 10 metrów. Tak więc jak ulokować budynki,a by nie nachodziły na siebie, były zwrócone do drogi i połączone z nią. i wszystkie akcje wykonany na polu zajmowanym przez np. budynek zajmujący 2x3 pola, dotyczyły całego budynku. Posiadam 2 wymiarową tablice mapy w której są przechowywane informacja nt. wysokości pola, sprite pola, typ pola (np. skała, trawa, piasek, itp.) typ strefy (mieszkalna, przemysłowa, itd.). Pytanie: Gdzie umieścić budynki. W obiektach pól czy w osobnym vectorze.

Przykład
Przykład

Mam nadzieje, że ująłem jasno wszystkie aspekty problemu. Czekam na sugestie.
P-58594
Admixior
» 2012-06-17 14:03:19
i wszystkie akcje wykonany na polu zajmowanym przez np. budynek zajmujący 2x3 pola, dotyczyły całego budynku
Tutaj nasuwa mi się że każde pole będzie zawierało ten sam wskaźnik do jednego budynku.
P-58596
Schulze13
Temat założony przez niniejszego użytkownika
Błędy w zarządzaniu RAM w tablicy mapy
» 2012-06-17 15:01:37
Jeszcze problem z wielkością mapy :P. Gdy chce aby mapa była większa niż 256, np. 512 na 512, wywala mi "Unhandled exception at 0x00953b27 in 4WorldCity.exe: 0xC00000FD: Stack overflow."
C/C++
class cCity
{
public:
   
    cCity( void )
    {
        ptrB = NULL;
       
        for( int i = 0; i < 512; i++ )
        {
            for( int j = 0; j < 512; j++ )
            {
                ptrB = new cBlok;
                mapa[ i ][ j ] = ptrB;
                delete ptrB;
            }
        }
        std::cout << "\ngotowe mapa ma " << sizeof( mapa ) << " bajtow";
        ptrB = NULL;
    }
   
    virtual ~cCity( void )
    {
       
    }
   
private:
   
    cBlok * ptrB;
    cBlok * mapa[ 512 ][ 512 ];
   
    cBudynek * ptrH;
    std::vector < cBudynek > budynki;
};
C/C++
class cBlok
{
public:
   
    cBlok( void )
    {
        //std::cout << "blok";
    }
   
    virtual ~cBlok( void )
    {
    }
private:
    sf::Sprite spBlok;
   
    int wysokoscBlok;
   
    cBudynek * budynek;
   
};
P-58605
Admixior
» 2012-06-17 20:56:47
Źle chyba pojąłeś pojęcie alokacji i dealokacji.
C/C++
ptrB = new cBlok;
mapa[ i ][ j ] = ptrB;
delete ptrB;
alokujesz i masz adres załóżmy 0x00220000 nowej pamięci.
Później przypisujesz do mapy; mapa[ i ][j]=0x00220000;
i Dealokujesz czyli usuwasz rezerwacje "0x00220000"; od teraz to nie twój adres.
Ale chwila przecież później masz używasz mapa[ i ][ j ] gdzie jest ten adres!!!

//PS. usuń linijkę delete

//EDIT dealokujesz (kolejna pętla for) w destruktorze.
a zmienną ptrB możesz dać definicje w konstruktorze (chyba że ma ona iny głębszy cel)
P-58612
Schulze13
Temat założony przez niniejszego użytkownika
» 2012-06-18 12:49:24
Pamięciowy problem nie ustępuje nawet po usunięciu
delete ptrB;
 :[.
//1048576 pól to aż tak dużo na mapę? 65536 to jak dla mnie za mało na miasto.

@edit
Jakieś sugestie nt. przechowywania mapy? Najlepiej kod który inicjalizuje taką tablice[1024][1024] obiektami.

@edit
Jest postęp. Teraz treść komunikatu to "Unhandled exception at 0x04129ce8 in 4WorldCity.exe: 0xC0000005: Access violation." :).
P-58616
Admixior
» 2012-06-18 20:35:02
hmm...
Problem nie jest z rezerwacją:
Uno: Chyba że piszesz pod DOS-em tam wskaźniki mają do 65535 wartości. A w 32bit mają wartość unsigned int = 0xffffffff; 232 czyli sporo(zobacz na wiki jak chcesz mieć tę liczbę.

Duo: Jeżeli zabraknie pamięci to zostanie rzucony wyjątek "std::bad_alloc" (jak będziesz chciał wiedzieć jak to chwycić to napisz. Jeżeli nie chwycisz to program się wysypie widząc odpowiedni komunikat o niezłapanym wyjątku.

Tres: Jeżeli użyłbyś
int * wsk = new( std::nothrow ) xx;
 to wtedy nie będzie wyjątku tylko "wsk==NULL" będzie prawdziwe.

Quatro: Najprostszym sposobem chyba będzie na początku programu wywołanie funkcji set_new_handler gdzie podajesz nazwę (=adres) funkcji wywoływanej bez parametrów zwracającej void która zostanie wywołana w razie gdyby nastąpił wyjątek omówiony w punkcie  "Duo" (nie można używać z punktem "Tres")

//nie wiem jakiej libki używasz ale weź podrzuć kod i/lub zdebuguj i zobacz dokładnie przy której funkcji wychodzi ten błąd bo inaczej nici z tego.
A ten błąd to ja obstawiam że gdzieś deklarujesz wskaźnik na stosie po czym nie przypisując mu nic używasz.
P-58668
Schulze13
Temat założony przez niniejszego użytkownika
» 2012-06-18 21:30:46
Platforma: win7 x64. Visual C++. Kod dostarcze jak najszybciej( czemu niema IDE na androida ;p ). Troche jaśniej nt. set_new_handler? Wyszukiwarka na stronie zawiodła.
P-58673
Admixior
» 2012-06-18 21:53:18
Co do set_new_handler()
C/C++
void brak_pamieci()
{
    cout << "brak pamieci";
    //jakiekolwiek inne działanie
}

int main()
{
    set_new_handler( brak_pamieci );
    ///<i dalej kod>
}

Jeżeli wtedy zabraknie pamięci to wywoła się funkcja brak_pamieci();
jest ona w nagłówku <new.h>
P-58676
« 1 » 2
  Strona 1 z 2 Następna strona