PDA

Visualizza la versione completa : [c] Indirizzi scomparsi!


pistilloi
08-09-2013, 21:47
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.



#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)

pistilloi
09-09-2013, 17:36
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:


/**
*
*
*/
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... :confused: :confused: :confused:

oregon
10-09-2013, 11:36
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.

pistilloi
10-09-2013, 11:45
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)

oregon
10-09-2013, 11:51
Non è un errore ... y deve essere uguale a 4 per terminare il ciclo ... non ci vedo nulla di strano

pistilloi
10-09-2013, 13:58
gia hai ragione, inoltre avevo sottodimensionato l'array around! Ora fila tutto liscio...

Loading