Combining Trees and Nodes, value unaccessible
i'm experimenting with trees and nodes and I having trouble. I have
typedef struct nodo
{
int cuenta;
int fondo;
struct nodo *sig;
}pNodo;
typedef pNodo *tLista;
typedef struct tree
{
int RUT;
struct tree *izq;
struct tree *der;
struct nodo *tLista;
}tTree;
typedef tTree *tABB;
typedef tTree *tNodo;
void crearArbol(tABB arbol)
{
tABB nuevoA;
nuevoA=(tABB)malloc(sizeof(tTree));
arbol=nuevoA;
arbol->izq=NULL;
arbol->der=NULL;
}
int AgregarCuenta(tABB *arbol,int rut,int id_cuenta,int saldo)
{
tABB AUX;
AUX=*arbol;
tLista nuevaC;
int i=1;
if(AUX==NULL)
{
crearArbol(AUX);
if(id_cuenta==1)
{
(AUX->tLista)->fondo=saldo;
return 0;
}
else
{
return -1;
}
}
else
{
if(rut==AUX->RUT)
{
while(AUX->tLista!=NULL)
{
if(AUX->tLista->cuenta==id_cuenta)
{
return -1;
}
else
{
AUX->tLista=AUX->tLista->sig;
i++;
}
}
nuevaC=(tLista)malloc(sizeof(pNodo));
nuevaC->sig=NULL;
nuevaC->cuenta=i;
nuevaC->fondo=saldo;
AUX->tLista=nuevaC;
return 0;
}
else
{
if(rut<AUX->RUT)
{
AUX=AUX->izq;
AgregarCuenta(&AUX,rut,id_cuenta,saldo);
}
开发者_运维问答 else
{
AUX=AUX->der;
AgregarCuenta(&AUX,rut,id_cuenta,saldo);
}
}
}
}
int main()
{
tABB arbolillo;
crearArbol(arbolillo);
AgregarCuenta(&arbolillo, 18020200, 1, 9999);
return 0;
}
It dies on "(AUX->tLista)->fondo=saldo;" at the AgregarCuenta function. with "EXC_BAD_ACCESS"
What am I doing wrong?
I believe crearArbol
requires a pointer to a pointer as input:
void crearArbol(tABB *arbol)
{
tABB nuevoA = (tABB)malloc(sizeof(tTree));
if (nuevoA == 0)
...handle out of memory error...
*arbol = nuevoA;
(*arbol)->izq = NULL;
(*arbol)->der = NULL;
}
And the call:
crearArbol(&AUX);
Otherwise, you don't 'return' the value to the calling code.
Additionally, just after that you have:
if(id_cuenta==1)
{
(AUX->tLista)->fondo=saldo;
return 0;
}
But if you've just called crearArbol()
there is no initialization of the tLista
member, so it points at garbage. You need to allocate the space for it to point to, and set the tLista
member to point to it; then you can set the fondo
member of that allocated space. Make sure you initialize every member of every structure...
Update 1: fixed notation in crearArbol()
- the extra parentheses are needed. You also have to worry about the call to crearArbol()
in main()
, which I missed before. You are missing a return
from AgregarCuenta()
, or the return type should be void
and the other return
statements in the function would lose the value. Since you don't check the returned value, it is not clear which is better.
Update 2: this code compiles and runs. It leaks memory, of course.
#include <stdlib.h>
typedef struct nodo
{
int cuenta;
int fondo;
struct nodo *sig;
}pNodo;
typedef pNodo *tLista;
typedef struct tree
{
int RUT;
struct tree *izq;
struct tree *der;
struct nodo *tLista;
}tTree;
typedef tTree *tABB;
typedef tTree *tNodo;
static void crearArbol(tABB *arbol)
{
tABB nuevoA = (tABB)malloc(sizeof(tTree));
*arbol=nuevoA;
(*arbol)->izq = NULL;
(*arbol)->der = NULL;
(*arbol)->tLista = malloc(sizeof(pNodo));
(*arbol)->tLista->cuenta = -1;
(*arbol)->tLista->fondo = -1;
(*arbol)->tLista->sig = NULL;
}
static int AgregarCuenta(tABB *arbol, int rut, int id_cuenta, int saldo)
{
tABB AUX;
AUX=*arbol;
tLista nuevaC;
int i=1;
if(AUX==NULL)
{
crearArbol(&AUX);
if(id_cuenta==1)
{
(AUX->tLista)->fondo=saldo;
return 0;
}
else
{
return -1;
}
}
else
{
if(rut==AUX->RUT)
{
while(AUX->tLista!=NULL)
{
if(AUX->tLista->cuenta==id_cuenta)
{
return -1;
}
else
{
AUX->tLista=AUX->tLista->sig;
i++;
}
}
nuevaC=(tLista)malloc(sizeof(pNodo));
nuevaC->sig=NULL;
nuevaC->cuenta=i;
nuevaC->fondo=saldo;
AUX->tLista=nuevaC;
return 0;
}
else
{
if(rut<AUX->RUT)
{
AUX=AUX->izq;
return AgregarCuenta(&AUX,rut,id_cuenta,saldo);
}
else
{
AUX=AUX->der;
return AgregarCuenta(&AUX,rut,id_cuenta,saldo);
}
}
}
}
int main(void)
{
tABB arbolillo;
crearArbol(&arbolillo);
AgregarCuenta(&arbolillo, 18020200, 1, 9999);
return 0;
}
When run with valgrind
, I get:
==25013== Memcheck, a memory error detector
==25013== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==25013== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==25013== Command: tree
==25013==
==25013== Conditional jump or move depends on uninitialised value(s)
==25013== at 0x100000DC0: AgregarCuenta (tree.c:54)
==25013== by 0x100000EC5: main (tree.c:95)
==25013==
==25013== Conditional jump or move depends on uninitialised value(s)
==25013== at 0x100000E52: AgregarCuenta (tree.c:77)
==25013== by 0x100000EC5: main (tree.c:95)
==25013==
==25013==
==25013== HEAP SUMMARY:
==25013== in use at exit: 184 bytes in 5 blocks
==25013== total heap usage: 5 allocs, 0 frees, 184 bytes allocated
==25013==
==25013== LEAK SUMMARY:
==25013== definitely lost: 64 bytes in 2 blocks
==25013== indirectly lost: 32 bytes in 2 blocks
==25013== possibly lost: 0 bytes in 0 blocks
==25013== still reachable: 88 bytes in 1 blocks
==25013== suppressed: 0 bytes in 0 blocks
==25013== Rerun with --leak-check=full to see details of leaked memory
==25013==
==25013== For counts of detected and suppressed errors, rerun with: -v
==25013== Use --track-origins=yes to see where uninitialised values come from
==25013== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
精彩评论