Data convertion

Hi, I'm making a C program (not C++) and I have a problem.

I've created this data type:

typedef struct {

char ArrayChar[9] ;

int Probability[9] ;

} tpBoard ;

and I need to store a variable of the type tpBoard inside a list but the value of is of the void type:

This is the node:

typedef struct tgNode {

struct tgNode * pNext ;

struct tgNode * pPrev ;

void * Value ;

} tpNode ;

that belongs to the list:

typedef struct tgList {

tpNode * pFirst ;
tpNode * pFirst ;

} tpList ;

So, I use typecast:

(...)
tpBoard * Board;
tpList * List ;
tpNode * Node;
void * ValueToBeInsertedInTheList;
(...)

ValueToBeInsertedInTheList= (void * ) Board;
Node->Value = ValueToBeInsertedInTheList;

Then, I insert that node in the list.
But, when I need to check the Value inside that node, I need to typecast it back:

(...)
Board = (tpBoard * )(Node->Value);

Problem is that, when I do that, half of the data comes screwed up. For instance, the Board has the variable CharArray[9]. Like... chars from [0] to [3] are glitched, but chars [4] to [8] are okay.
I've read somewhere that you can lose data when you convert data to void * and then convert it back. So, how can I make it so I can do that convertion without losing data.

Again, I'm using C and not C++.

Thanks in advance,
ze
[1573 byte] By [ze1] at [2007-11-20 11:48:43]
# 1 Re: Data convertion
Please use [CODE] tags around your sample code.

Where are you allocating the memory for the Board variable?

It sounds like that the variable may be going out of scope or the memory is getting released somehow between the time you store it and the time you retrieve it.
kenrus at 2007-11-9 1:26:17 >
# 2 Re: Data convertion
All variable memories are allocated using malloc()
ze1 at 2007-11-9 1:27:14 >
# 3 Re: Data convertion
Again, please use code tags. I don't see any reference to 'malloc' in your code, so the problem must be in code you're not showing.

Please post all the code, or a small and compilable testcase that represents the problem you're having. With the snippets you posted, there are no obvious errors.

Viggy
MrViggy at 2007-11-9 1:28:13 >
# 4 Re: Data convertion
This is a basically tic-tac-toe with (crappy) AI.
The variable names and such are in Portuguese. I hope it won't be a problem.

This is the part of the code that "trains" the computer.

// structure of the board
typedef struct {

// array that contains the 'X' and 'O' of the board
char VetorCasa[9] ;
/* O valor contido na casa. Pode conter ' ', 'O' ou 'X',
que simboliza Casa vazia, jogada feita pelo usuario e
pelo computador, respectivamente */

// probability of the computer choosing that place to set the character
int Probabilidade[9] ;
/* A probabilidade do computador escolher a casa */

} tpTabuleiro ;

// structure of the value that will be put in the node that will be inserted in the list
typedef struct {

int JogadaTab ;
/* Casa escolhida pelo jogador aprendiz */

// a copy of the board that will be inserted in the list
tpTabuleiro Tabuleiro ;
/* Referencia um tabuleiro */

} tpValorNoLista ;

void JGO_Treinamento ( ptLista * pListaJogada , tpTabuleiro * TabuleiroJogo )
{

int i, j, NumeroEscolhido, VetorRandomizar[9] , NovoVetorProbabilidade[9] ;
int Usu = 0, Comp = 0;
tpValorNoLista * ConfigTabuleiro = ( tpValorNoLista * ) malloc ( sizeof ( tpValorNoLista ) ) ;
tpValorNoLista * Aux = ConfigTabuleiro;
tpValorNoLista * ValorCorrente = ( tpValorNoLista * ) malloc ( sizeof ( tpValorNoLista ) ) ;
LST_tpCondRet RetornoLista ;
JOG_tpCondRet RetornoJogada ;

printf("\nAdestrando o computador. Aguarde...\n");

if ( ConfigTabuleiro == NULL || ValorCorrente == NULL )
{
printf("\nErro ao alocar memria para variveis crticas ao programa\n");
system("pause");
}

for( i = 0 ; i < 9 ; i ++ )
ConfigTabuleiro->Tabuleiro.VetorCasa[i] = VAZIO;

for ( i = 0 ; i < 9 ; i ++ )
NovoVetorProbabilidade[i] = 1000;

/* Durante o treinamento, o computador aprendiz ser representado pelos smbolos de usurio */

for ( j = 0 ; j < 1000 ; j ++ )
{

/* Reinicia o tabuleiro do jogo novo */
for ( i = 0 ; i < 9 ; i ++ )
{
TabuleiroJogo->VetorCasa[i] = VAZIO ;
}

ConfigTabuleiro->JogadaTab = -1 ;

do
{

ConfigTabuleiro = Aux;

RetornoLista = LST_Pesquisar ( pListaJogada , (void *) TabuleiroJogo , CompTabuleiro ) ;

if ( RetornoLista == LST_CondRetListaVazia || RetornoLista == LST_CondRetNaoAchou )
{

/* Atribui as probabilidades e cria o vetor de char que representa o tabuleiro */
for ( i = 0 ; i < 9 ; i ++ )
{

if( TabuleiroJogo->VetorCasa[i] == VAZIO )
{
VetorRandomizar[i] = TabuleiroJogo->Probabilidade[i] ;
}
else
{
VetorRandomizar[i] = 0 ;
}

}

for ( i = 0 ; i < 9 ; i ++ )
{
ConfigTabuleiro->Tabuleiro.Probabilidade[i] = TabuleiroJogo->Probabilidade[i] ;
ConfigTabuleiro->Tabuleiro.VetorCasa[i] = TabuleiroJogo->VetorCasa[i] ;
}

if( LST_InserirNo( pListaJogada, (void*)ConfigTabuleiro ) != LST_CondRetOK )
{
printf( "\nNo foi possvel inserir a configurao atual do tabuleiro na Lista.\n" );
system("pause") ;
}
else
{
printf("\nINSERIU O TABULEIRO:\n");
JOG_MostrarTabuleiro(ConfigTabuleiro->Tabuleiro.VetorCasa);
}

Aux = ( tpValorNoLista * ) malloc ( sizeof ( tpValorNoLista ) ) ;
Aux->JogadaTab = -1 ;

for( i = 0 ; i < 9 ; i ++ )
Aux->Tabuleiro.VetorCasa[i] = VAZIO;

} else {
printf ( "AHA!!!");
fflush(stdin);
getch();
}

JOG_PreencherVetorJogadas ( VetorRandomizar ) ;

/* Jogada do Computador computador */
//printf("\ncomputador:\n");
RetornoJogada = JOG_CriarJogada ( TabuleiroJogo->VetorCasa ) ;

JOG_RetornarVetorJogadas ( TabuleiroJogo->Probabilidade ) ;

if ( RetornoJogada == JOG_CondRetMemoria )
{
printf( "\nOcorreu um erro de memria ao criar a jogada do computador.\n" );
system("pause") ;
}
else
{

RetornoJogada = JOG_verificarTabuleiro(TabuleiroJogo->VetorCasa) ;
//RetornoJogada = JOG_MostrarTabuleiro(TabuleiroJogo->VetorCasa) ;

if ( RetornoJogada == JOG_CondRetOK )
{

/* Jogada do Computador aprendiz */

/* Atribui as probabilidades e cria o vetor de char que representa o tabuleiro */
for ( i = 0 ; i < 9 ; i ++ )
{

if( TabuleiroJogo->VetorCasa[i] == VAZIO )
{
VetorRandomizar[i] = TabuleiroJogo->Probabilidade[i] ;
}
else
{
VetorRandomizar[i] = 0 ;
}

}
JOG_PreencherVetorJogadas( VetorRandomizar ) ;
//printf("\naprendiz:\n");
RND_Randomizar ( VetorRandomizar , &NumeroEscolhido ) ;

ConfigTabuleiro->JogadaTab = NumeroEscolhido;
TabuleiroJogo->VetorCasa[NumeroEscolhido-1] = USUARIO ;
TabuleiroJogo->Probabilidade[NumeroEscolhido-1] -= 1 ;
JOG_PreencherVetorJogadas( VetorRandomizar ) ;
RetornoJogada = JOG_MostrarTabuleiro(TabuleiroJogo->VetorCasa) ;

}

}

} while (RetornoJogada == JOG_CondRetOK );

if ( RetornoJogada == JOG_CondRetUsuarioGanhou )
Usu++;
else
if ( RetornoJogada == JOG_CondRetComputadorGanhou )
Comp++;

if ( RetornoJogada == JOG_CondRetUsuarioGanhou || RetornoJogada == JOG_CondRetVelha )
{

if ( LST_IrPrimeiro ( pListaJogada ) != LST_CondRetListaVazia )
{

for ( ; RetornoLista != LST_CondRetFimLista ; RetornoLista = LST_IrProximo ( pListaJogada ) )
{

if ( LST_ObterCorrente( pListaJogada , &ValorCorrente ) == LST_CondRetOK )
{

if ( ValorCorrente->JogadaTab != -1 )
{
ValorCorrente->Tabuleiro.Probabilidade[ValorCorrente->JogadaTab-1] += 2;
NovoVetorProbabilidade[ValorCorrente->JogadaTab-1] = ValorCorrente->Tabuleiro.Probabilidade[ValorCorrente->JogadaTab-1];
}

}

}

}

for ( ; RetornoLista != LST_CondRetFimLista ; RetornoLista = LST_IrProximo ( pListaJogada ) )
{

if ( LST_ObterCorrente( pListaJogada , &ValorCorrente ) == LST_CondRetOK )
{
ValorCorrente->JogadaTab = -1;
}

}

}

for ( i = 0 ; i < 9 ; i ++ )
TabuleiroJogo->Probabilidade[i] = NovoVetorProbabilidade[i];

//printf("LOOP DE JOGOS!!!\n");
}
printf("FIM DE TUDO: APRENDIZ: %d ||| COMPUTADOR: %d\n", Usu , Comp );

}

int CompTabuleiro ( void * tabuleiro1 , void * tabuleiro2 )
{

int i;
tpTabuleiro * TabuleiroComp1;
tpTabuleiro * TabuleiroComp2;

TabuleiroComp1 = ( tpTabuleiro * ) tabuleiro1;
TabuleiroComp2 = ( tpTabuleiro * ) tabuleiro2;

for ( i = 0 ; i < 9 ; i ++ )
if( TabuleiroComp1->VetorCasa[i] != TabuleiroComp2->VetorCasa[i] )
return 0 ;

return 1 ;

}

And this is the part of the code that deals with the list structure:

// structure of the node of the list
typedef struct tgNoLista {

// pointer to the node that is next to the current one
struct tgNoLista * pNoProx ;
/* Ponteiro para o n seguinte ( direita)
*
*$EED Assertivas estruturais
* se pNoProx do n X != NULL ento pNoAnt de pNoProx aponta para o n X */

// pointer to the previous node
struct tgNoLista * pNoAnt ;
/* Ponteiro para o n anterior ( esquerda)
*
*$EED Assertivas estruturais
* se pNoAnt do n X != NULL ento pNoProx de pNoAnt aponta para o n X */

void * Valor ;
/* Valor do n */

} tpNoLista ;

// structure of the head node of the list
typedef struct tgNoCab {

// pointer to the first node in the list
struct tgNoLista * pNoPrim ;
/* Ponteiro para o primeiro n da lista
*
*$EED Assertivas estruturais
* se pNoPrim == NULL, ento pNoCorr == NULL e lista est vazia */

// pointer to the current node
struct tgNoLista * pNoCorr ;
/* Ponteiro para o n corrente da lista
*
*$EED Assertivas estruturais
* se pNoCorr->pNoAnt == NULL e pNoCorr->pNoProx == NULL, ento
pNoPrim = pNoCorr */

} tpNoCab ;

// structure of the list
typedef struct tgLista {

// pointer to the head of the list
tpNoCab * pNoCab ;
/* Ponteiro para o n cabea da lista */

} tpLista ;

// inserts a new node into the list
LST_tpCondRet LST_InserirNo( ptLista * Lista , void * ValorParm )
{
tpLista * pLista = ( tpLista * )Lista ;

tpNoLista * pNo ;

pNo = CriarNo( ValorParm ) ;

if ( pNo == NULL )
{
return LST_CondRetMemoria ;
} /* if */

if( ! ( pLista->pNoCab->pNoPrim ) )
{
pLista->pNoCab->pNoCorr = pLista->pNoCab->pNoPrim = pNo;
}
else
{
/* As atribuies a seguir so feitas para alocar o n na lista */

if( pLista->pNoCab->pNoCorr->pNoProx )
pLista->pNoCab->pNoCorr->pNoProx->pNoAnt = pNo ;

pNo->pNoProx = pLista->pNoCab->pNoCorr->pNoProx ;
pNo->pNoAnt = pLista->pNoCab->pNoCorr ;
pLista->pNoCab->pNoCorr->pNoProx = pNo ;

} /* if */

/* O n novo se torna o n corrente */
pLista->pNoCab->pNoCorr = pNo;

return LST_CondRetOK ;

} /* Fim funo: LST Inserir n */

// returns the value that is pointed by
LST_tpCondRet LST_ObterCorrente( ptLista * Lista, void ** ValorParm )
{
tpLista * pLista = (tpLista *)Lista ;

if ( pLista->pNoCab->pNoPrim == NULL )
{
return LST_CondRetListaVazia ;
} /* if */

* ValorParm = pLista->pNoCab->pNoCorr->Valor ;

return LST_CondRetOK ;

} /* Fim funo: LST Obter corrente */

// Searches the node that contains the desired value
LST_tpCondRet LST_Pesquisar( ptLista * Lista , void * EstrComp , int (*func)(void *, void *) )
{

tpNoLista * pPercorre;
tpLista * pLista = (tpLista *)Lista ;

if ( pLista->pNoCab->pNoPrim == NULL )
{
return LST_CondRetListaVazia ;
} /* if */

for( pPercorre = pLista->pNoCab->pNoPrim ; pPercorre != NULL ; pPercorre = pPercorre->pNoProx )
{
if ( ((*func)(pPercorre->Valor, EstrComp)) == 1 )
return LST_CondRetAchou;
}

return LST_CondRetNaoAchou;

} /* Fim funo: LST Pesquisar N */

/***** Cdigo das funes encapsuladas no mdulo *****/

// creates the node that will be inserted in the list
tpNoLista * CriarNo( void * ValorParm )
{

tpNoLista * pNo ;

pNo = ( tpNoLista * ) malloc( sizeof( tpNoLista )) ;

if ( pNo == NULL )
{
return NULL ;
} /* if */

pNo->pNoAnt = NULL ;
pNo->pNoProx = NULL ;
pNo->Valor = ValorParm ;
return pNo ;

} /* Fim funo: LST Criar n da lista */

I hope it's clear enough.

ze
ze1 at 2007-11-9 1:29:13 >