[ Goran Arandjelovic @ 08.09.2005. 21:42 ] @
Zasto ovo puca? Obratite paznju na matrix promenljivu...dolazi do problema kada pokusam da oslobodim mem. u desktruktoru...sta se desava?
Ako mozete..najbolje je da iskompajlirate sa gcc-om. Koristim gcc3.3.4.

Code:

#include<iostream>
#include<fstream>
using namespace std;

class field
{
    public:
        field(int n, int m);
        ~field();
        void set(int n, int m, char v);
        char get(int n, int m);
    private:
        char **matrix;
        int x,y;
};

void generate_map(int density, field &rf);
char random_trees(int density);

int main(int argc, char *argv[])
{
    field pf(10,10);
}

field::field(int n, int m)
{
    matrix = new char*[n-1];
    for(int i=0;i<n;i++) matrix[i] = new char[m-1];
    x = n; y = m;
}

field::~field()
{
    for(int i=0;i<x;i++) delete[] matrix[i];
}

inline void field::set(int n, int m, char v)
{
    if((n<1 || m<1) || (n>x || m>y)) return;
    matrix[n-1][m-1] = v;
}

inline char field::get(int n, int m)
{
    if((n<1 || m<1) || (n>x || m>y)) return(-1);
    return(matrix[n-1][m-1]);
}

void generate_map(int density, field &rf)
{
    if(density<2) density=2;
    if(density>9) density=9;
}

char random_trees(int density)
{
    char ret_val;
    fstream rnd("/dev/urandom",ios::in|ios::binary);
    rnd.read((char*)&ret_val,sizeof(char));
    rnd.close();
    if(ret_val%density==0) return('*');
    return(' ');
}
[ igac @ 08.09.2005. 22:01 ] @
ne znam... meni ne puca gcc 3.3.1 iz dev-cpp4.9.9.1
[ Reljam @ 08.09.2005. 22:09 ] @
Los ti je konstruktor. Za n=1, ocigledno ne radi. Treba da promenis red:

matrix = new char*[n-1];

u

matrix = new char*[n];
[ yooyo @ 08.09.2005. 22:14 ] @
Ovde je greska...

Code:

field::field(int n, int m) // neka su n i m = 10
{
    matrix = new char*[n-1]; // alociras 9 elementata i to sa indexima 0..8
    for(int i=0;i<n;i++) matrix[i] = new char[m-1]; // kada i postane 9, bombardujes memoriju jer za matrix[9] nije alociran prostor.
    x = n; y = m;
}


Pravilno bi bilo:
Code:

field::field(int n, int m)
{
    matrix = new char*[n];
    for(int i=0;i<n;i++) matrix[i] = new char[m];
    x = n; y = m;
}


yooyo
[ Goran Arandjelovic @ 08.09.2005. 22:34 ] @
Hvala Reljo, hvala Yooyo...to je to. I sada je samo potrebno da udarim glavom o zid, zato sto sam pomislio da ako se kaze x = new char[9], x ima indekse...x[0],x[1]....x[9]!
Uzas...
Jos jednom vam hvala.
[ itf @ 09.09.2005. 10:12 ] @
Možda bi bilo dobro da uzmeš u obzir i eventualnu neuspjelu dinamičku alokaciju, pa postaviš i neku poruku i za slučaj toga...
[ Dragi Tata @ 09.09.2005. 13:17 ] @
A i destruktor ti nije kompletan, mada to ne može da izazove pucanje programa, već samo curenje memorije.

Uzgred, pogledaj ovo: http://www.boost.org/libs/multi_array/doc/user.html
[ Dragi Tata @ 09.09.2005. 13:22 ] @
I još nešto:

Šta se desi kad uradiš nešto kao:

field a(10,10), b(10,10);
a = b;

[ Goran Arandjelovic @ 09.09.2005. 15:27 ] @
Posto nisam definisao copy constructor mogu da se dese sledece stvari..mozda sam nesto izostavio..

kopiraju se samo vrednosti x i y
a za matricu se kopiraju samo vrednosti pokazivaca, a ne i cele matrice
i plus.. ako se objektu sa vecom matricom dodeli objekat sa manjom matricom ostatak pokazivaca ce 'izvisiti'

Nego, sta sam izostavio u destruktoru?... ispravi me ako gresim, ali mislim da je potrebno obrisati samo clanove kojima je dinamicki dodeljena memorija.
[ Dragi Tata @ 09.09.2005. 16:59 ] @
Citat:
Goran Arandjelovic: Posto nisam definisao copy constructor mogu da se dese sledece stvari..mozda sam nesto izostavio..

kopiraju se samo vrednosti x i y
a za matricu se kopiraju samo vrednosti pokazivaca, a ne i cele matrice
i plus.. ako se objektu sa vecom matricom dodeli objekat sa manjom matricom ostatak pokazivaca ce 'izvisiti'


Tako je, ali još gore je što na tako kopirane pointere pozivaš dva puta delete u destruktorima objekata, a to može da dovede to kraha.

Citat:
Goran Arandjelovic
Nego, sta sam izostavio u destruktoru?... ispravi me ako gresim, ali mislim da je potrebno obrisati samo clanove kojima je dinamicki dodeljena memorija.


Pa kad pozoveš
Code:
for(int i=0;i<x;i++) delete[] matrix[i];

to oslobađa memoriju alociranu sa
Code:
for(int i=0;i<n;i++) matrix[i] = new char[m];


Međutim, deo alociran sa
Code:
matrix = new char*[n-1];

nigde nije obrisan.

Generalno savetujem ljudima da se klone tih new-delete petljancija i koriste gotove klase (STL, Boost, MFC, Borland,... ko šta voli) osim kad se baš mora.

[Ovu poruku je menjao Dragi Tata dana 09.09.2005. u 18:00 GMT+1]
[ Reljam @ 09.09.2005. 17:17 ] @
Nisi obrisao sam matrix:
delete[] matrix;
[ Goran Arandjelovic @ 09.09.2005. 18:07 ] @
Aha..jasno, jasno.

@Dragi Tata
I u pravu si...koriscenje nekih biblioteka bi olaksalo zivot, ali bi takav slucaj brisanja mogao verovatno da se obradi izuzecima :))
[ Dragi Tata @ 09.09.2005. 18:28 ] @
Citat:
Goran Arandjelovic: ali bi takav slucaj brisanja mogao verovatno da se obradi izuzecima :))


Hmmm, mislim da Standard ne zahteva da se kod duplog brisanja baci izuzetak. Tu ja vidim tri rešenja:

1) Da implementiraš copy konstruktor i operator = tako da napravi kopiju matrica a ne samo pointera.

2) Da deklarišeš gorepomenute funkcije kao privatne, pa će onda kompajler da te spreči da uradiš ono što sam ja gore napisao.

3) Da udariš neki reference counting pa da tek poslednji destruktor pozove delete.

Ali ja ti ipak savetujem boost::multi_array ;)