Newsgroup: it.comp.lang.c++
Titolo: Perchè questo comportamento?

Ciao a tutti,
sto realizzando un programmino per l'università ed ho bisogno di una
classe matrice.
Per fare un po' di esercizio mi sono messo a scriverla personalmente
ma ho riscontrato degli strani comportamenti da parte del compilatore.
Il codice è:
//---
main.cpp
//---
#include "matrix.h"
int main(int argc, char *argv[])
{
    matrix m(10,5);
    return 0;
}
//----
matrix.h
//----
#define _NOMEM 100
#define ME (*this)
#define __USANEW 1
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
class matrix
{
    private:
        //----
        double *mat;
        unsigned nr, nc;
        //----
        void allocator(unsigned r, unsigned c);
        void deallocator(void);
    public:
        matrix();
        matrix(matrix& m) {ME=m;}; //costruttore di copia
        matrix(unsigned r, unsigned c) {mat=NULL; allocator(r, c);};
//costruttore matrice r.x.c
        matrix(unsigned n) {mat=NULL; allocator(n,n);}; //costruttore
matrice n.x.n
        ~matrix();
        double& operator()(unsigned r, unsigned c) const;
        void setto(const double d);
};
void matrix::allocator(unsigned r, unsigned c)
{
    if(mat!=NULL)
        deallocator();
#if __USANEW
    mat=(double*)new double[r*c];
    //mat=(double*)new double[r][c];
#else
    mat=(double*)malloc(sizeof(double)*r*c);
#endif
    if(mat==NULL)
        exit(_NOMEM);
    nr=r;
    nc=c;
    setto(0.0);
}
void matrix::deallocator(void)
{
#if __USANEW
    delete[] mat;
#else
    free(mat);
#endif
    mat=NULL;
    nr=nc=0;
}
matrix::matrix()
{
    mat=NULL;
    nr=nc=0;
}
matrix::~matrix()
{
    deallocator();
}
void matrix::setto(const double d)
{
    unsigned r, c;
    for(r=0;r<nr;r++)
        for(c=0;c<nc;c++)
            ME(r,c)=d;
}
double& matrix::operator()(unsigned r, unsigned c) const
{
    if(r<0 || r>=nr || c<0 || c>=nc)
        exit(_NOINDEX);
    return mat[nr*r+c];
}
ora il problema è che se nel main dichiaro la matrice quadrata tutto
funziona, se invece la matrice è generica il programma si inchioda!
Ho compilato sia con VC++ che con DEV-C++ ed il comportamento è circa
lo stesso.
Perchè? Dove sbaglio?
Grazie e ciao Ste.
Stefano
stsTO...@freemail.it
 (occhio all'antispam)

     return mat[nr*r+c];
deve invece essere
       return mat[nc*r+c];
altrimenti scrivi in zona di memoria non allocata.
cosa che non succedeva,essendo il problema invisibile per le matrici
quadrate.
Maurus


Grazie mille, non me ne sarei mai accorto!!
Ste.

 a écrit dans le message news:
ukrlauo957mq7mblh...@4ax.com...

Di nulla,
con un po' di allenamento e un minimo di debugging te ne accorgeresti
credimi.
L'importante e' partire dal fatto che se abbiamo un problema a tempo di
esecuzione,
il problema nel 99,9% dei casi e' causato da noi.
Specialmente per quei problemi di scritture su memoria non allocata (come in
questo caso) o gia' liberata (dangling pointer: quando si considera' un
puntatore ancora vivo mentre questi e' morto essendo locale a una funzione)
o cose similari.
Non dare mai la colpa al compilatore, perche' questo atteggiamento ti
farebbe solo sprecare un mucchio di tempo.
Parti sempre dal fatto che il bug e' causato dal tuo codice e vallo a
cercare col debugging.
Maurus

#define __USANEW 1
Non ho letto il tuo messaggio perché ho visto che ti hanno già
risposto ma mi è caduto l'occhio su quel __USANEW. I nomi che
contengono un doppio underscore sono riservati.
-- 
Marco Barisione (ICQ 84277092)


Sono perfettamente d'accordo con te, 
il problema è che, forse per mia inesperienza, non riesco ad eseguire
il debug del codice...cioè il debugger mi si inchioda!
Mi sono scaricato il cygnus insight debugger per comodità e quando
eseguo il debug del codice si inchioda quando è sul "new" e mi da come
messaggio: "program recived signal SIGSEGV, segmentation fault", e poi
va alla graffa di chiusura del main.
C'è qualcosa che non so? La versione del debugger è la 5.0, Dev-C++ è
il 4.0, il compilatore Mingw è il 2.95.2-1.
Grazie Ste.



Scusami ma in questo caso non so aiutarti.
Non ho mai usato il debugger con DevC++.
Debuggo sempre usando il VisualC++.
Forse stavolta e' veramente un baco che non dipende da te!
Maurus