Newsgroup: it.comp.lang.c
Titolo: Mistero!

Innanzitutto lasciatemi ringraziare tutti coloro che hanno risposto alla
mia richiesta di aiuto su <<come generare tutte le possibili
combinazioni>>.Ho imparato qualcosa da ognuno di voi.Grazie davvero.
Ora passiamo al mistero...
Nel main() di un mio programma ho dichiarato e - contestualmente -
inizializzato una matrice di unsigned di dimensione 8 (matrix).
Inoltre ho dichiarato una seconda matrice (temp) come puntatore ad
unsigned e l'ho inizializzata con  temp=(unsigned*)calloc(8*8,sizeof(unsigned))
A questo punto ho fatto un ciclo per copiare ogni riga di matrix nella
rispettiva riga di temp in questo modo:
         for (i=0;i<8;i++)
           copyRow (temp+8*i , matrix+8*i ,8);
dove la funzione copyRow e' cosi' dichiarata:
         void copyRow (unsigned *destin,unsigned *origin,unsigned dim)
           {
              unsigned index;
              for (index=0 ; index<dim ; index++)
                  *(destin+index)=*(origin+index);
           }                
Mi sapreste dire perche' usando copyRow( temp+8*i , matrix+8*i ,8)
viene segnalato un errore di SEGMENTATION FAULT (quindi errore di accesso
alla memoria),mentre tutto va bene usando
copyRow( temp+8*i , matrix+i ,8) oppure copyRow( temp+8*i , *temp+8*i ,8)
Grazie,Fabio.

copyRow( temp+8*i , matrix+i ,8) oppure copyRow( temp+8*i , *temp+8*i ,8)
Io credo che *temp+8+i sia errato perche' *temp non e' un puntatore.
In quanto al primo caso, secondo me deriva dal fatto che probabilmente hai
definito matrix come 
unsigned matrix[8][8] ; 
e quindi scrivere "matrix" non equivale a scrivere "il puntatore ad 1 unsigned"
ma "&matrix[0]", ed essendo "matrix[0]" un array di 8 unsigned, in pratica
"matrix" e' l'indirizzo di un array di 8 unsigned e quindi scrivere "matrix + i"
equivale a scrivere "(unsigned*)matrix + 8*i".
E' giusto che "copyRow( temp+8*i , matrix+i ,8)" funzioni.
Osserva il programma d'esempio che ti riporto di seguito :
#include <stdio.h>
int main()
{
    char matrix[8][8] = { "aaaaaaa", "bbbbbbb",
                          "ccccccc", "ddddddd",
                          "eeeeeee", "fffffff",
                          "ggggggg", "hhhhhhh" } ;
    int i ;
    printf("sizeof( *matrix ) = %d\n", sizeof ( *matrix ) );
    for (i = 0 ; i < 8 ; i++ ) /* scrive l'array per stringhe */
        printf("%s\n", matrix + i );
    printf("sizeof( * (char *) matrix ) = %d\n", sizeof ( *(char*)matrix ) );
    for (i = 0 ; i < 8*8 ; i++ )  /* scrive l'array carattere per carattere */
        putchar(*((char *)matrix + i));
    printf("\n");
    return 0 ;
}
Skyscraper (
andrea_...@bigfoot.com
)
--
Posted from 
itaca.ulysse.it
 [195.223.254.1]
via Mailgate.ORG Server - 
http://www.mailgate.org

 
Pare che il news server si sia perso il mio msg precedente, quindi riposto:
Per il C matrix+i == matrix[i], cioe' ((char *)matrix)+(i*8*sizeof(unsigned
int)): il compilatore tiene gia' conto della dimensione di una riga della
matrice. Scrivere matrix+i*8 sarebbe come scrivere matrix[i*8] e si finisce
per accedere a memoria non mappata nello spazio di indirizzamento del
processo  (segmentation fault).
E' giusto scrivere:
copyRow( temp+8*i , matrix+i ,8);
Ma sarebbe meglio lasciare fare al compilatore:
typedef struct {
  unsigned int mat[8][8];
} mat8x8_t;
ma8x8_t matrix;
mat8x8_t *temp=calloc(1, sizeof(mat8x8_t));	// Creazione di una matrice
dinamica
matrix.mat[x][y];	// Accesso agli elementi della matrice
*temp=matrix;	// Copia la matrice
temp->mat[x][y]	// Accesso alla matrice dinamica;

 
Ho capito, ma non ho capito (e questo non l'avevo specificato nella mia
precedente) perche' in un' altra applicazione, sempre dichiarando una
matrice
sigma[6][6] e sempre usando *(sigma+6*i+j) per ottenere l'elemento
sigma[i][j]  non da' alcun problema!
Fabio.

 copyRow( temp+8*i , matrix+i ,8) oppure copyRow( temp+8*i , *temp+8*i ,8)
Eccoti una versione funzionante del tuo programma:
#include <stdio.h>
#include <stdlib.h>
void copyRow (unsigned *destin,unsigned *origin,unsigned dim)
{
    unsigned index;
    for (index=0 ; index<dim ; index++)
        *(destin+index)=*(origin+index);
}
int main()
{
    unsigned matrix [ 8 ][ 8 ];
    unsigned **temp = 0;
    int i, j;
    for ( i = 0; i < 8; ++i )
        for ( j = 0; j < 8; ++j )
            matrix[ i ][ j ] = i * 8 + j;
    printf( "\n" );
    for ( i = 0; i < 8; ++i )
    {
        for ( j = 0; j < 8; ++j )
            printf( "%2u ", matrix[ i ][ j ] );
        printf( "\n" );
    }
    for ( i = 0; i < 8; ++i )
    {
        temp[ i ] = calloc( 8 * 8, sizeof( unsigned ) );
        if ( temp[ i ] == 0 )
        {
            printf( "Memoria insufficiente\n" );
            return 1;
        }
    }
    printf( "\n" );
    for ( i = 0; i < 8; ++i )
    {
        for ( j = 0; j < 8; ++j )
            printf( "%2u ", temp[ i ][ j ] );
        printf( "\n" );
    }
    for ( i = 0; i < 8; ++i )
        copyRow( temp[ i ], matrix[ i ], 8 );
    printf( "\n" );
    for ( i = 0; i < 8; ++i )
    {
        for ( j = 0; j < 8; ++j )
            printf( "%2u ", temp[ i ][ j ] );
        printf( "\n" );
    }
    return 0;
}
EMG

sigma[i][j]  non da' alcun problema!
Il C non e' un'opinione ;) .
*(sigma+6*i+j) non e' la scrittura corretta per accedere a sigma[i][j].
scrivere a[i][j] equivale a scrivere *( *( a + i ) + j ).
Difatti se risolvi l'espressione :
"a" e' un array di 6 array di 6 unsigned.
"*(a+i)" equivale per definizione a "a[i]", quindi l'array i-esimo.
scrivere "a[i] + j" viene convertito in "&a[i] + j" cioe' l'indirizzo del
j-esimo elemento dell'i-esimo array e quindi "*(a[i]+j)" significa "il valore
puntato dall'indirizzo dell'j-esimo elemento dell'i-esimo array", ovvero "il
j-esimo elemento dell'i-esimo array" (cioe' a[i][j]).


        temp[ i ] = calloc( 8 * 8, sizeof( unsigned ) );
                             ^^^^^
         temp[ i ] = calloc( 8 , sizeof( unsigned ) ) ;


          temp[ i ] = calloc( 8 , sizeof( unsigned ) ) ;
Oopss! Inconvenienti del copia e incolla... :-( Grazie della correzione.
EMG

 
E' sicuramente sbagliato:
  (sigma+6*i+j) ==> sigma[6*i+j] !
Ma, se accedi sempre (lettura/scrittura) con la notazione (sigma+6*i+j)
potrebbe far finta di funzionare a secondo di che cosa viene allocato dopo
la matrice: in realta' accedi a memoria che non appartiene alla matrice ma
se non corrompi strutture usate da altri e il Sistem Operativo ti alloca
comunque memoria in piu' (magari per arrotondare alla dimensione di una
pagina di memoria) il programma funziona.
Per dimostrarlo prova a stampare l'indirizzo di sigma[i][j] e di
sigma+6*i+j, oppure aggiungi un array 'char dummy[1000]' subito dopo la
matrice sigma, riempilo di zeri e, dopo aver riempito sigma (non di zeri),
vai a vedere il contenuto dell'array dummy. Ovviamente dovresti fare la
prova modificando il programma "funzionante".