Newsgroup: it.comp.os.linux.development
Titolo: Memoria e array

Sto facendo un programmino che richiede una particolare matrice.. 
se imposto i valori della matrice int dopo aver allocato 10 righe ho 
segmentation fault.. mentre mettendolo register tutto ok.. perchč? vabbe 
che la matrice č abbastanza grande ma insomma..
il programmino č:
#include <stdio.h>
#include <stdlib.h>
#define LINEE 20
int main(){
        register **a;
        int row,col;
        for(row=0;row<LINEE;row++){
                (*(a+row))=(int*)malloc((LINEE-row)*sizeof(int));
                printf("%i\n",row);
                }
        for(row=0; row<LINEE; row++)
                for(col=0; col<(LINEE-row); col++)
                       (*(a+row)+col)=col;
         for(row=0; row<LINEE; row++)
                for(col=0; col<(LINEE-row); col++)
                        printf("%i",*(*(a+row)+col));
       return 0;
}

                 (*(a+row))=(int*)malloc((LINEE-row)*sizeof(int));
Se non sbaglio
 - a non e' stato allocato;
 - a+row punta chissa' dove;
 - *(a+row) = ... sovrascrive chissa' cosa;
 - in cast per malloc non e' necessario.
C:\>iao Angelo
P.S. E chiamare a con un nome un pelo piu' significativo :-)

 
chiedo scusa mancano un po' di asterischi..Il cast su malloc e' (int 
*)malloc(..)   poi e'  *(*(a+row)+col)=.. inserisco il valore della cella..
poi ti chiedo una cosa: ma io non alloco a con malloc?
Cmq grazie!

Francesco wrote:


Scusa un attimo ma lo spazio per contenere l'array di puntatori non l'allochi? Tipo
a = (void *) malloc(sizeof(void *) * LINEE);
Se lo fai poi ha senso scrivere
*(a+row)= bla bla bla
Ciao Mei

                }
Non hai allocato memoria per l'array individuato da 'a':
a = malloc(LINEE * sizeof(void*));
E non usare cast sul risultato di malloc()!
-- 
Saluti,
    Mardy
http://www.interlingua.com

Allora ho capito di non usare il cast su malloc, ma io devo definire una 
matrice la cui prima riga ha 20 (LINEE) colonne, la seconda che ne abbia 
19, la terza 18... fino ad arrivare alla riga 20 che contiene un solo 
valore..
per questo volevo allocare ogni riga in maniera autonoma con 
(a+row) = malloc((LINEE-row)*sizeof(int)
Insomma vorrei fare una matrice diciamo "Triangolare"...
Questo è il modo che mi è venuto in mente x farlo.
Qualcuno di voi ha qualche idea alternativa?
Il problema è forse che prima devo allocore i 20 puntatori alle 20 righe di 
lunghezza variabile e poi allocare le righe?
Grazie

 poi ti chiedo una cosa: ma io non alloco a con malloc?
Puntatori, brutta bestia. :-)
Effettivamente la malloc serve per allocare memoria, ma tu non hai
fatto la malloc per riservare memoria per i puntatori alle righe.
quello che avresti dovuto fare      Quello che hai fatto
a -> +---+                          a ->
     |   |      +-+-+-+-+-+-+-+                     +-+-+-+-+-+-+-+
     | +------->| | | | | | | |            +------->| | | | | | | |
     |   |      +-+-+-+-+-+-+-+                     +-+-+-+-+-+-+-+
     +---+
     |   |      +-+-+-+-+-+-+                       +-+-+-+-+-+-+
     | +------->| | | | | | |              +------->| | | | | | |
     |   |      +-+-+-+-+-+-+                       +-+-+-+-+-+-+
     +---+
     |   |      +-+-+-+-+-+                         +-+-+-+-+-+
     | +------->| | | | | |                +------->| | | | | |
     |   |      +-+-+-+-+-+                         +-+-+-+-+-+
     +---+
       .                                   .
       .                                   .
       .                                   .
     +---+
     |   |      +-+                                 +-+
     | +------->| |                        +------->| |
     |   |      +-+                                 +-+
     +---+
       ^                                   ^
       |                                   |
       arrary di puntatori                 memoria non allocata
E' chiaro che nella seconda condizione tutto puo' avvenire. Magari
il tuo programma avrebbe potuto funzionare per molto tempo prima di
dare problemi: trovare a distanza di mesi il problema non e' affatto
facile. Esperienza personale su un caso non troppo diverso da questo.
Quello che manca e'
  a = malloc(LINEE*sizeof(int*));
Inoltre perche' hai utilizzato la notazione (*(a+row)+col) = col?
Questa notazione, oltre ad essere piu' prona agli errori (e infatti
e' sbagliata, come ti sei accorto tu stesso) e' anche molto meno
leggibile di
    a[row][col] = col;
E ti garantisco che l'effetto e' assolutamente identico a quello
di
   *(*(a+row)+col) = col; :-)
Piccola nota, se avessi inizializzato a a NULL ti saresti accorto
subito che qualcosa non andava.
 per 0 == row
 (*(NULL + 0)) = malloc(); ---> BUUUUM!!
molti non inizializzano le variabili, io le inizializzo sempre:
costa poco e spesso salva il culo :-)
Un metodo migliore e', in fase di debug, usare qualche libreria
tipo efence che rileva gli accessi al memoria non allocata o
oltre la zona allocata.
Infine dare allle variabili nomi significativi non e' un vezzo da
minchioni, prova a rinominare "a" nel tuo file: io trovo 8 occorrenze
di a di cui 3 non si riferiscono a quello che si vuole sostituire:
circa un 40% di errori, non male :-)
Il codice corretto e' quello riportato sotto (con qualche piccola
modifica).
<CODE>
#include <stdio.h>
#include <stdlib.h>
#define LINEE 20
int main(void)
{
   int row        = 0;
   int col        = 0;
   int** matrixPP = NULL;
   matrixPP = malloc(LINEE * sizeof(int*));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Questa mancava!!!
   for(row = 0; row < LINEE; row++)
   {
      matrixPP[row] = malloc((LINEE -row) * sizeof(int));
      printf("%i\n", row);
   }
   printf("--------------------\n");
   for(row = 0; row < LINEE; row++)
      for(col = 0; col < (LINEE -row); col++)
         matrixPP[row][col] = col;
   for(row = 0; row < LINEE; row++)
   {
     for(col = 0; col < (LINEE -row); col++)
        printf("%i ", matrixPP[row][col]);
     printf("\n");
   }
   return 0;
}
</CODE>
Spero di essere stato chiaro & non troppo prolisso.
C:\>iao Angelo.
P.S. Su it.comp.lang.c ci sono state feroci discussioni sul perche'
     il cast della malloc e' inutile e a volte pericoloso. Una
     ricerca su Deja non farebbe male :-)
     Questo e' un problema di "C", la prossima volta posta su iclc,
     da quelle parti sono tutti disposti a darti una mano, qui magari
     qualcuno si urta per l'OT.

lunghezza variabile e poi allocare le righe?
Esatto.


 oltre la zona allocata.
Le libc hanno gia` tutto quello che serve:
mtrace(), muntrace() per tracciare le chiamate a malloc/realloc/free
mprobe() per fare un controllo sulla consistenza di un'area di memoria
compilare con -lmcheck per attivare in modo automatico il controllo
sulla consistenza.
Per i dettagli: info libc "Unconstrained Allocation"
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Se non puoi convincerli, confondili.

 
Grazie per l'aggiornamento, daro' sicuramente un'occhiata.
C:\>iao Angelo.

 Qualcuno di voi ha qualche idea alternativa?
Se vuoi allocare una matrice triangolare ti basterebbe un vettore di
lunghezza (n*(n+1))/2 dove per i<=j l'elemento (i,j) della matrice ha indice
(j*(j-1))/2+i (spero di non fare gaffe con gli indici dovute all'ora tarda).
Se non ti tornano i conti o sei interessato alla dimostrazione matematica
proseguiamo per email perche' qui saremmo OT.
--
Alessandro Staltari
staltari(a)
geocities.com