Novo

Forum kao aplikacija na telefonu

Dodajte forum na početni ekran i koristite ga kao aplikaciju, sa menijem na dnu ekrana.

  • 12 odgovora
  • 5.877 pregleda

Najnovija ↓

Ne znam zasto puca (char**) 08.09.2005. u 22:42 · pre 257 meseci #1
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(' ');
}
Re: Ne znam zasto puca (char**) 08.09.2005. u 23:01 · pre 257 meseci #2
ne znam... meni ne puca gcc 3.3.1 iz dev-cpp4.9.9.1
Potpis
"nice town, i'll take it..."
Re: Ne znam zasto puca (char**) 08.09.2005. u 23:09 · pre 257 meseci #3
Los ti je konstruktor. Za n=1, ocigledno ne radi. Treba da promenis red:

matrix = new char*[n-1];

u

matrix = new char*[n];
Re: Ne znam zasto puca (char**) 08.09.2005. u 23:14 · pre 257 meseci #4
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
Re: Ne znam zasto puca (char**) 08.09.2005. u 23:34 · pre 257 meseci #5
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.
Re: Ne znam zasto puca (char**) 09.09.2005. u 11:12 · pre 257 meseci #6
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...
Re: Ne znam zasto puca (char**) 09.09.2005. u 14:22 · pre 257 meseci #8
I još nešto:

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

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

Potpis
IOCC
Re: Ne znam zasto puca (char**) 09.09.2005. u 16:27 · pre 257 meseci #9
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.
Re: Ne znam zasto puca (char**) 09.09.2005. u 17:59 · pre 257 meseci
izmenjeno 1 put, poslednji put Dragi Tata 09.09.2005. u 18:00
  1. Dragi Tata09.09.2005. u 18:00zapis iz teksta poruke
#10
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.
Potpis
IOCC
Re: Ne znam zasto puca (char**) 09.09.2005. u 18:17 · pre 257 meseci #11
Nisi obrisao sam matrix:
delete[] matrix;
Re: Ne znam zasto puca (char**) 09.09.2005. u 19:07 · pre 257 meseci #12
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 :))
Re: Ne znam zasto puca (char**) 09.09.2005. u 19:28 · pre 257 meseci #13
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 ;)
Potpis
IOCC
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme