Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [c] Indirizzi scomparsi!

    Buonasera,
    Sto lavorando a una funzione che data una matrice di Letter e una stringa; cerca nella matrice la stringa unendo Letter adiacenti.
    Il mio problema sorge nella funzione around_of_letter(), la quale dovrebbe trovare e salvare l'indirizzo delle Letter adiacenti(attorno) ad'ogni elemento della matrice.

    codice:
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    
    #define SIDE 4
    #define true 1
    #define false 0
    
    typedef int Bool;
    
    typedef struct Point { int x; int y; } Pnt;
    
    typedef struct Letter{	
    	
    	char letter;	
    	struct Letter * around[8]; 
    	Pnt position;
    	
    } Letter;
    
    typedef Letter **Matrix;
    
    
    /**
     * 
     *
     */ 
    Matrix matrix_new( int N, int M ) {
    	
    	Matrix matrix;
    	int i;
    	
    	matrix = (Matrix) malloc( N * sizeof(Letter*) ) ;
    	for (i=0; i<N; ++i)
    		matrix[i] = (Letter*) malloc( M * sizeof(Letter) )
    			;
    	return matrix ;
    }
    
    
    /**
     * 
     *
     */ 
    int distance_between_letters( Letter L1, Letter L2 )  {
    	Pnt p1 = L1.position ;
    	Pnt p2 = L2.position ;
    	return (int) sqrt(pow(p2.x-p1.x,2)+pow(p2.y-p1.y,2))
    		;
    }
    
    
    /**
     * 
     *
     */
    void around_of_letter( Matrix M, Letter *L) {
    	
    	int x,y;
    	int i=0;
    	
    	for(x=0; x<SIDE; x++)
    		for(y=0; y<SIDE; y++) {
    			
    			if( distance_between_letters( M[x][y], *L ) == 1 ) 
    				L->around[i++] = &M[x][y] 
    					;
    			else 
    				L->around[i++] = NULL
    					;
    		}
    }
    
    
    /**
     * 
     *
     */
    Matrix matrix_fill( Matrix M, char *W ) {
    	
    	int x,y;
    	int i = 0;
    	
    	for(x=0; x<SIDE; x++)
    		for(y=0; y<SIDE; y++)  { 
    			 M[x][y].letter = W[i++];
    			 M[x][y].position.x = x;
    			 M[x][y].position.y = y;
    			 around_of_letter( M, &M[x][y] ) ;
    		}
    	return M ;
    }
    
    
    /**
     * 
     *
     */
    Bool search_on_matrix( Matrix M, Letter * L )  {
    	
    	int x,y;
    	for(x=0; x<SIDE; x++)
    		for(y=0; y<SIDE; y++)  
    			if( M[x][y].letter == L->letter ) {
    				L = &M[x][y] ;
    				return true ;
    			}
    			else 
    				return false ;
    }
    
    /**
     * 
     *
     */
    Bool search_on_around( Letter * L, char C )  {
    	
    	int i;
    	for(i=0; i<8; i++) 
    
    		if( L->around[i] != NULL && L->around[i]->letter == C )	{	
    			L = L->around[i] ; 
    			return true ;
    		}
    		else 
    			return false ;
    }
    
    /**
     * 
     *
     */
    Bool automatic_gamer( Matrix M, char *W ) {
    	
    	int x,y;
    	int i = 0;
    	Letter L;
    
    	do {
    		switch(i) {
    			
    			case 0:
    				
    				L.letter = W[i];
    				if( !search_on_matrix( M, &L ) )
    					return false 
    						;
    				break;
    		
    			default:
    				
    				if( !search_on_around( &L, W[i] ) )
    					return false 
    						;
    				break;
    		}
    	} while( W[i++] != '\0' ) ;
    	
    	return true ;
    }
    
    
    
    void main()  {
    	
     Matrix M = matrix_new(4,4);
     
     matrix_fill( M, "ciao0123456789||" ) ;
    		
    	if(automatic_gamer(M,"ciao"))
    		printf("true!")
    			;
    	else printf("false!");
    }
    Posto anche una sessione di gdb nella quale si nota che non vengon salvati gli indirizzi nell'array "around" membro della struct Letter.
    $ cc prova.c -lm -g
    $ gdb ./a.out
    GNU gdb (GDB) 7.5.91.20130417-cvs-ubuntu
    Copyright (C) 2013 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from /home/dante/Documenti/Ruzzle/0.3/a.out...done.
    (gdb) list around_of_letter
    54
    55 /**
    56 *
    57 *
    58 */
    59 void around_of_letter( Matrix M, Letter *L) {
    60
    61 int x,y;
    62 int i=0;
    63
    (gdb) break 60
    Breakpoint 1 at 0x4007d7: file prova.c, line 60.
    (gdb) run
    Starting program: /home/dante/Documenti/Ruzzle/0.3/a.out
    warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000

    Breakpoint 1, around_of_letter (M=0x603010, L=0x603040) at prova.c:62
    62 int i=0;
    (gdb) next
    64 for(x=0; x<SIDE; x++)
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], *L ) == 1 )
    (gdb) next
    71 L->around[i++] = NULL
    (gdb) print L
    $1 = (Letter *) 0x603040
    (gdb) print *L
    $2 = {letter = 99 'c', around = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, position = {x = 0, y = 0}}
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], *L ) == 1 )
    (gdb) next
    71 L->around[i++] = NULL
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], *L ) == 1 )
    (gdb) next
    71 L->around[i++] = NULL
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], *L ) == 1 )
    (gdb) next
    71 L->around[i++] = NULL
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    64 for(x=0; x<SIDE; x++)
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], *L ) == 1 )
    (gdb) next
    71 L->around[i++] = NULL
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], *L ) == 1 )
    (gdb) next
    71 L->around[i++] = NULL
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], *L ) == 1 )
    (gdb) next
    71 L->around[i++] = NULL
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) print *L
    $3 = {letter = 99 'c', around = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, position = {x = 0, y = 0}}
    (gdb)
    Dante

  2. #2
    Ho individuato un'evidente errore, andavo a determinare l'intorno del punto senza prima inizializzare tutti gli elementi della matrice. Ho quindi modificato due funzioni:

    codice:
    /**
     * 
     *
     */
    Letter around_of_letter( Matrix M, Letter L) {
    	
    	int x,y;
    	int i=0;
    	
    	for(x=0; x<SIDE; x++)
    		for(y=0; y<SIDE; y++) {
    			
    			if( distance_between_letters( M[x][y], L ) == 1 ) 
    				L.around[i++] = &M[x][y]
    					;
    			else 
    				L.around[i++] = NULL
    					;
    		}
    	return L ; 
    }
    
    
    /**
     * 
     * 
     */
    Matrix matrix_fill( Matrix M, char *W ) {
    	
    	int x,y;
    	int i = 0;
    	
    	for(x=0; x<SIDE; x++)
    		for(y=0; y<SIDE; y++)  { 
    			 M[x][y].letter = W[i++];
    			 M[x][y].position.x = x;
    			 M[x][y].position.y = y;
    		}
    	for(x=0; x<SIDE; x++)
    		for(y=0; y<SIDE; y++)
    			M[x][y] = around_of_letter( M, M[x][y] ) 
    				; 
    	return M ;
    }
    Ma il problema persiste, inoltre in Letter.position sovente trovo salvati valori in'attesi e improponibili, tra l'altro molto simili agli indirizzi della zona di memoria in cui lavoro. Cio provoca caos nel calcolo delle distanze e cosi di seguito.
    Non me ne capacito...
    Dante

  3. #3
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,299
    Con un po' di debug passo passo dovresti riuscire a trovare la "causa prima" dei problemi (ovvero un'area non allocata, non inizializzata, un puntatore con un valore sballato ...) per poi cercare di capire le mancanze nell'algoritmo e così via.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  4. #4
    Già, dovrei! Si trattasse solo di puntatori con valori sballati, qua ad'esempio ho scoperto che la variabile y nel for viene incrementata sino a 4 pur essendo limitata a y<4.

    $ gdb a.out
    (gdb) list around_of_letter
    54
    55 /**
    56 *
    57 *
    58 */
    59 Letter around_of_letter( Matrix M, Letter L) {
    60
    61 int x,y;
    62 int i=0;
    63
    (gdb)
    64 for(x=0; x<SIDE; x++)
    65 for(y=0; y<SIDE; y++) {
    66
    67 if( distance_between_letters( M[x][y], L ) == 1 )
    68 L.around[i++] = &M[x][y]
    69 ;
    70 else
    71 L.around[i++] = NULL
    72 ;
    73
    (gdb) break 64
    Breakpoint 1 at 0x4007de: file prova.c, line 64.
    (gdb) run
    Starting program: /home/dante/Documenti/Ruzzle/0.3/a.out

    Breakpoint 1, around_of_letter (M=0x603010, L=...) at prova.c:64
    64 for(x=0; x<SIDE; x++)
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], L ) == 1 )
    (gdb) print y
    $1 = 0
    (gdb) next
    71 L.around[i++] = NULL
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], L ) == 1 )
    (gdb) print y
    $2 = 1
    (gdb) next
    68 L.around[i++] = &M[x][y]
    (gdb) print y
    $3 = 1
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], L ) == 1 )
    (gdb) next
    71 L.around[i++] = NULL
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    67 if( distance_between_letters( M[x][y], L ) == 1 )
    (gdb) next
    71 L.around[i++] = NULL
    (gdb) next
    65 for(y=0; y<SIDE; y++) {
    (gdb) next
    64 for(x=0; x<SIDE; x++)
    (gdb) print y
    $4 = 4
    (gdb)
    Dante

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,299
    Non è un errore ... y deve essere uguale a 4 per terminare il ciclo ... non ci vedo nulla di strano
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  6. #6
    gia hai ragione, inoltre avevo sottodimensionato l'array around! Ora fila tutto liscio...
    Dante

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2020 vBulletin Solutions, Inc. All rights reserved.