› Foros › PC › Software libre
struct Coordenadas{
int x, y;
};
typedef struct Tail{
struct Coordenadas c;
struct Tail *next;
} * ptrTail;
typedef struct Head{
ptrTail first, last;
int numElem;
} * ptrHead;
//Prototipos
ptrHead anadir(int coordx, int coordy, ptrHead p);
ptrHead borrar(int coordx, int coordy, ptrHead p);
void borrarTodo(ptrHead p);
void imprimir(ptrHead p);
#include <stdio.h>
#include <stdlib.h>
#include "head_tail_list.h"
ptrHead anadir(int coordx, int coordy, ptrHead p){
if(p == NULL){
p=(ptrHead) malloc(sizeof(struct Head));
p->first=(ptrTail) malloc(sizeof(struct Tail));
p->numElem=1;
p->first->c.x=coordx;
p->first->c.y=coordy;
p->first->next=NULL;
p->last=p->first;
return p;
}
p->last->next=(ptrTail) malloc(sizeof(struct Tail));
p->last->next->c.x=coordx;
p->last->next->c.y=coordy;
p->last->next->next=NULL;
p->last=p->last->next;
p->numElem++;
return p;
}
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p==NULL)
return NULL;
int i;
ptrTail t=p->first, t1=t;
for(i=0; i < p->numElem; i++){
if(t->c.x==coordx && p->first->c.y==coordy){
t=t->next;
free(t1);
p->numElem--;
}
t=t->next;
t1=t;
}
return p;
}
void borrarTodo(ptrHead p){
int i;
ptrTail t=p->first, t1=t;
for(i=0; i< p->numElem; i++){
t=t->next;
free(t1);
t1=t;
}
free(p);
return;
}
void imprimir(ptrHead p){
int i;
ptrTail t=p->first;
printf("El número de nodos es %d\n", p->numElem);
for(i=0; i < p->numElem; i++){
printf("Nodo %d:\n Coordenada x %d\n Coordenada y %d\n", i, t->c.x, t->c.y);
t=t->next;
}
}
#include <stdio.h>
#include "head_tail_list.h"
int main(int arg_count, char *arg_strings[]) {
printf("Tienes las siguientes opciones para hacer:\n - Pulsa 'a' para añadi un elemento a la lista.\n - Pulsa 'r'para borrar un elemento de la lista.\n- Pulsa 'p' para imprimir todos los nodos.\n - Pulsa 'q' para salir.\n");
char var;
int x,y;
ptrHead p=NULL;
scanf("%s",&var);
while(var != 'q'){
switch(var){
case 'a':
printf("Introduzca las coordenadas x e y a añadir\n");
scanf("%d %d",&x, &y);
p=aniadir(x,y,p);
break;
case 'r':
printf("Introduzca las coordenadas x e y a borrar\n");
scanf("%d %d",&x, &y);
p=borrar(x,y,p);
break;
case 'p':
imprimir(p);
break;
}
}
borrarTodo(p);
return 0;
}
gcc -c head_tail_list.c
gcc head_tail_list.o main.c -o nombrePrograma
nu_kru escribió:mm.. lo lógico es que el fichero de cabeceras tenga el mismo nombre que el fichereo que lo implementa
Para compilar haz:gcc -c head_tail_list.c
gcc head_tail_list.o main.c -o nombrePrograma
Con gcc -c lo que hace es compilar el fichero pero no lo linka.
gcc *.c -o ejecutable
CC := gcc
TARGET = ejecutable
LIBS :=
INCLUDES :=
LIB_PATH :=
CFLAGS := -O2 -pipe -Wall
LDFLAGS :=
RM = rm -f
OBJS = main.o list.o
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) $(LIB_PATH) $(LIBS) -o $(TARGET)
.c.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $*.c
clean:
-$(RM) $(OBJS) $(TARGET)
.PHONY: all clean
Chaky escribió:Este es un problema con las universidades, que te enseñan con un IDE, te dicen que el IDE es el compilador, y luego no se sabe no lo que es el makefile ni compilar manualmente. Una simple clase explicando lo que es cada cosa y me habría quitado muchos quebraderos de cabeza...
struct Coordenadas{
int x, y;
};
typedef struct Tail{
struct Coordenadas c;
struct Tail *next;
} * ptrTail;
typedef struct Head{
ptrTail first, last;
int numElem;
} * ptrHead;
//Prototipos
ptrHead anadir(int coordx, int coordy, ptrHead p);
ptrHead borrar(int coordx, int coordy, ptrHead p);
void borrarTodo(ptrHead p);
void imprimir(ptrHead p);
#include <stdio.h>
#include <stdlib.h>
#include "head_tail_list.h"
ptrHead anadir(int coordx, int coordy, ptrHead p){
if(p == NULL){
p=(ptrHead) malloc(sizeof(struct Head));
p->first=(ptrTail) malloc(sizeof(struct Tail));
p->numElem=1;
p->first->c.x=coordx;
p->first->c.y=coordy;
p->first->next=NULL;
p->last=p->first;
return p;
}
p->last->next=(ptrTail) malloc(sizeof(struct Tail));
p->last->next->c.x=coordx;
p->last->next->c.y=coordy;
p->last->next->next=NULL;
p->last=p->last->next;
p->numElem++;
return p;
}
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p==NULL)
return NULL;
int i, aux=p->numElem;
ptrTail t=p->first;
for(i=0; i< aux; i++){
ptrTail t1=t;
if(t->c.x == coordx && t->c.y == coordy){
t=t1->next;
p->numElem--;
free(t1);
}
else
t=t->next;
}
return p;
}
void borrarTodo(ptrHead p){
int i;
ptrTail t=p->first, t1=t;
for(i=0; i< p->numElem; i++){
t1=t->next;
free(t);
t=t1;
}
free(p);
}
void imprimir(ptrHead p){
int i;
ptrTail t=p->first;
printf("El número de nodos es %d\n", p->numElem);
for(i=0; i < p->numElem; i++){
printf("Nodo %d:\n Coordenada x %d\n Coordenada y %d\n", i, t->c.x, t->c.y);
t=t->next;
}
}
#include <stdio.h>
#include "head_tail_list.h"
int main(int arg_count, char *arg_strings[]) {
char var='a';
int x,y;
ptrHead p=NULL;
while(var != 'q'){
printf("Tienes las siguientes opciones para hacer:\n - Pulsa 'a' para añadir un elemento a la lista.\n - Pulsa 'r' para borrar un elemento de la lista.\n - Pulsa 'p' para imprimir todos los nodos.\n - Pulsa 'q' para salir.\n");
scanf("%s",&var);
switch(var){
case 'a':
printf("Introduzca las coordenadas 'x' e 'y' a añadir\n");
scanf("%d %d",&x, &y);
p=anadir(x,y,p);
break;
case 'r':
if(p==NULL){
printf("No hay nodos que borrar.\n");
break;
}
printf("Introduzca las coordenadas 'x' e 'y' a borrar\n");
scanf("%d %d",&x, &y);
p=borrar(x,y,p);
break;
case 'p':
if(p==NULL){
printf("No hay nodos.\n");
break;
}
imprimir(p);
break;
}
}
if(p == NULL)
return 0;
borrarTodo(p);
return 0;
}
#! /bin/bash
echo Compiando head_tail_list.h
gcc -Wall -g head_tail_list.h
echo Compilando list.c
gcc -Wall -c -g list.c
echo Compilando main.c
gcc list.o -g main.c -o main
echo Probando desde valgrind
valgrind --leak-check=yes ./main
Ferdy escribió:En lugar de 'casca' igual deberías mirar con gdb qué es lo que está ocurriendo.
Donato escribió:Chaky escribió:Este es un problema con las universidades, que te enseñan con un IDE, te dicen que el IDE es el compilador, y luego no se sabe no lo que es el makefile ni compilar manualmente. Una simple clase explicando lo que es cada cosa y me habría quitado muchos quebraderos de cabeza...
Eso no es asi. Yo tiro de kate y terminal. El problema es que nunca habia compilado un *.c sin main() y me escupia error.
Otro tema, a ver si me echais un cable con la función de borrar un nodo. No hay forma de lo haga bien, borrar un nodo cualquiera dada sus coordenadas y no sé por qué. Aparentemente está bien, adjunto todo de nuevo por si alguien le apetece darle un repaso
head_tail_list.hstruct Coordenadas{
int x, y;
};
typedef struct Tail{
struct Coordenadas c;
struct Tail *next;
} * ptrTail;
typedef struct Head{
ptrTail first, last;
int numElem;
} * ptrHead;
//Prototipos
ptrHead anadir(int coordx, int coordy, ptrHead p);
ptrHead borrar(int coordx, int coordy, ptrHead p);
void borrarTodo(ptrHead p);
void imprimir(ptrHead p);
list.c#include <stdio.h>
#include <stdlib.h>
#include "head_tail_list.h"
ptrHead anadir(int coordx, int coordy, ptrHead p){
if(p == NULL){
p=(ptrHead) malloc(sizeof(struct Head));
p->first=(ptrTail) malloc(sizeof(struct Tail));
p->numElem=1;
p->first->c.x=coordx;
p->first->c.y=coordy;
p->first->next=NULL;
p->last=p->first;
return p;
}
p->last->next=(ptrTail) malloc(sizeof(struct Tail));
p->last->next->c.x=coordx;
p->last->next->c.y=coordy;
p->last->next->next=NULL;
p->last=p->last->next;
p->numElem++;
return p;
}
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p==NULL)
return NULL;
int i, aux=p->numElem;
ptrTail t=p->first;
for(i=0; i< aux; i++){
ptrTail t1=t;
if(t->c.x == coordx && t->c.y == coordy){
t=t1->next;
p->numElem--;
free(t1);
}
else
t=t->next;
}
return p;
}
void borrarTodo(ptrHead p){
int i;
ptrTail t=p->first, t1=t;
for(i=0; i< p->numElem; i++){
t1=t->next;
free(t);
t=t1;
}
free(p);
}
void imprimir(ptrHead p){
int i;
ptrTail t=p->first;
printf("El número de nodos es %d\n", p->numElem);
for(i=0; i < p->numElem; i++){
printf("Nodo %d:\n Coordenada x %d\n Coordenada y %d\n", i, t->c.x, t->c.y);
t=t->next;
}
}
main.c#include <stdio.h>
#include "head_tail_list.h"
int main(int arg_count, char *arg_strings[]) {
char var='a';
int x,y;
ptrHead p=NULL;
while(var != 'q'){
printf("Tienes las siguientes opciones para hacer:\n - Pulsa 'a' para añadir un elemento a la lista.\n - Pulsa 'r' para borrar un elemento de la lista.\n - Pulsa 'p' para imprimir todos los nodos.\n - Pulsa 'q' para salir.\n");
scanf("%s",&var);
switch(var){
case 'a':
printf("Introduzca las coordenadas 'x' e 'y' a añadir\n");
scanf("%d %d",&x, &y);
p=anadir(x,y,p);
break;
case 'r':
if(p==NULL){
printf("No hay nodos que borrar.\n");
break;
}
printf("Introduzca las coordenadas 'x' e 'y' a borrar\n");
scanf("%d %d",&x, &y);
p=borrar(x,y,p);
break;
case 'p':
if(p==NULL){
printf("No hay nodos.\n");
break;
}
imprimir(p);
break;
}
}
if(p == NULL)
return 0;
borrarTodo(p);
return 0;
}
prueba.sh (opcional, me quita trabajo xD)#! /bin/bash
echo Compiando head_tail_list.h
gcc -Wall -g head_tail_list.h
echo Compilando list.c
gcc -Wall -c -g list.c
echo Compilando main.c
gcc list.o -g main.c -o main
echo Probando desde valgrind
valgrind --leak-check=yes ./main
Uso valgrind para mirar las fugas de memoria.
La función que borra todos los nodos, lo hace bien; si creo muchos nodos y le doy a salir, antes del return, borro todos los nodos creados para que no haya fugas. Valgrind no chilla con eso. En cambio, cuando quiero borrar un nodo, casca.
Gracias de nuevo a todos por el cable
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p==NULL)
return NULL;
int i, aux=p->numElem;
ptrTail t=p->first;
for(i=0; i< aux; i++){
ptrTail t1=t;
if(t->c.x == coordx && t->c.y == coordy){
t=t1->next;
p->numElem--;
free(t1);
}
else
t=t->next;
}
return p;
}
Donato escribió:Ferdy escribió:En lugar de 'casca' igual deberías mirar con gdb qué es lo que está ocurriendo.
Estabas en el GUL de la uc3m verdad?
Ferdy escribió:Donato escribió:Ferdy escribió:En lugar de 'casca' igual deberías mirar con gdb qué es lo que está ocurriendo.
Estabas en el GUL de la uc3m verdad?
Hrm..... si.... ¿por qué?
Chaky escribió:Estas pasando a t la direccion del siguiente al que eliminar, pero ese t es un puntero que tu has declarado localmente, y cambiar este puntero no va a cambiar el del nodo anterior de la lista al que querias eliminar, no se si me explico... solo vas a cambiar ese puntero local, no el real que tienes en la lista.
PD: Seran cabrones los de mi unverisidad, que no te enseñan ni lo que es el IDE
PD2: Acabo de terminar un código que DEBERÍA de funcionar xD, pero a ver si lo consigues tu solo, que así se aprende mas xD
Chaky escribió:A ver, lo mejor es que te lo dibujes, es una forma sencilla de entender lo que estas haciendo.
Supongamos que el dato a borrar es [BORRAR], y t, t1 los punteros que tienes. Lo que veo que estas haciendo es esto:
t1->[BORRAR], t->[BORRAR], entonces luego haces que t->[SIG_BORRAR] y liberas la memoria a la que apunta t1 que es [BORRAR]. Pero ese t que apunta ahora a [SIG_BORRAR], no cambia nada en tu lista original, solo cambia la direccion de ese puntero que has creado localmente.
La idea, al menos siempre que hago una lista es la siguiente. Llevas dos punteros axiliares, uno que es el que borraremos, y otro que es el anterior, llamemoslo aux, antaux.
antaux->[ANT_BORRAR], aux->[BORRAR], entonces, ahora haces que el puntero next del [ANT_BORRAR] apunte al siguiente a borrar, en este caso: antaux->next=aux->next, y ahora, ya el [BORRAR] queda excluido de la lista, ahora ya puedes borrarlo.
Espero haberme explicado bien, es un poco complicado explicar esto por aquí.
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p==NULL)
return NULL;
ptrTail t=p->first;
ptrTail t1=p->first->next;
while(t != NULL){
if(t1->c.x == coordx && t1->c.y == coordy){
t->next=t1->next;
free(t1);
p->numElem--;
}
t=t->next;
}
return p;
}
Donato escribió:Chaky escribió:A ver, lo mejor es que te lo dibujes, es una forma sencilla de entender lo que estas haciendo.
Supongamos que el dato a borrar es [BORRAR], y t, t1 los punteros que tienes. Lo que veo que estas haciendo es esto:
t1->[BORRAR], t->[BORRAR], entonces luego haces que t->[SIG_BORRAR] y liberas la memoria a la que apunta t1 que es [BORRAR]. Pero ese t que apunta ahora a [SIG_BORRAR], no cambia nada en tu lista original, solo cambia la direccion de ese puntero que has creado localmente.
La idea, al menos siempre que hago una lista es la siguiente. Llevas dos punteros axiliares, uno que es el que borraremos, y otro que es el anterior, llamemoslo aux, antaux.
antaux->[ANT_BORRAR], aux->[BORRAR], entonces, ahora haces que el puntero next del [ANT_BORRAR] apunte al siguiente a borrar, en este caso: antaux->next=aux->next, y ahora, ya el [BORRAR] queda excluido de la lista, ahora ya puedes borrarlo.
Espero haberme explicado bien, es un poco complicado explicar esto por aquí.
El problema que tengo entonces es que no sé como liberar el del original xD
Donato escribió:He reditado mi post, a ver si es eso a lo que te refieres.
#include <stdio.h>
#include <stdlib.h>
#include "head_tail_list.h"
ptrTail actual=NULL, aux=NULL;
ptrHead anadir(int coordx, int coordy, ptrHead p){
if(p == NULL){
p=(ptrHead) malloc(sizeof(struct Head));
p->first=(ptrTail) malloc(sizeof(struct Tail));
p->numElem=1;
p->first->c.x=coordx;
p->first->c.y=coordy;
p->first->next=NULL;
p->last=p->first;
return p;
}
p->last->next=(ptrTail) malloc(sizeof(struct Tail));
p->last->next->c.x=coordx;
p->last->next->c.y=coordy;
p->last->next->next=NULL;
p->last=p->last->next;
p->numElem++;
return p;
}
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p->first->c.x == coordx && p->first->c.y == coordy){
ptrTail t=p->first;
p->first=p->first->next;
free(t);
}
actual=p->first->next;
aux=p->first;
while(actual != NULL){
if(actual->c.x == coordx && actual->c.y == coordy){
if(actual == p->last){
free(actual);
p->last=aux;
}
else{
aux->next=actual->next;
free(actual);
}
p->numElem--;
}
else
actual=actual->next;
}
return p;
}
void borrarTodo(ptrHead p){
actual=p->first->next;
aux=p->first;
while(actual !=NULL){
free(aux);
aux=actual;
actual=actual->next;
}
free(p);
}
void imprimir(ptrHead p){
int i=0;
ptrTail t=p->first;
printf("El número de nodos es %d\n", p->numElem);
while(t!= NULL){
printf("Nodo %d:\n Coordenada x %d\n Coordenada y %d\n", i, t->c.x, t->c.y);
t=t->next;
i++;
}
}
Donato escribió:#include <stdio.h>
#include <stdlib.h>
#include "head_tail_list.h"
ptrTail actual=NULL, aux=NULL;
ptrHead anadir(int coordx, int coordy, ptrHead p){
if(p == NULL){
p=(ptrHead) malloc(sizeof(struct Head));
p->first=(ptrTail) malloc(sizeof(struct Tail));
p->numElem=1;
p->first->c.x=coordx;
p->first->c.y=coordy;
p->first->next=NULL;
p->last=p->first;
return p;
}
p->last->next=(ptrTail) malloc(sizeof(struct Tail));
p->last->next->c.x=coordx;
p->last->next->c.y=coordy;
p->last->next->next=NULL;
p->last=p->last->next;
p->numElem++;
return p;
}
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p->first->c.x == coordx && p->first->c.y == coordy){
ptrTail t=p->first;
p->first=p->first->next;
free(t);
}
actual=p->first->next;
aux=p->first;
while(actual != NULL){
if(actual->c.x == coordx && actual->c.y == coordy){
if(actual == p->last){
free(actual);
p->last=aux;
}
else{
aux->next=actual->next;
free(actual);
}
p->numElem--;
}
else
actual=actual->next;
}
return p;
}
void borrarTodo(ptrHead p){
actual=p->first->next;
aux=p->first;
while(actual !=NULL){
free(aux);
aux=actual;
actual=actual->next;
}
free(p);
}
void imprimir(ptrHead p){
int i=0;
ptrTail t=p->first;
printf("El número de nodos es %d\n", p->numElem);
while(t!= NULL){
printf("Nodo %d:\n Coordenada x %d\n Coordenada y %d\n", i, t->c.x, t->c.y);
t=t->next;
i++;
}
}
Ultimos cambios.. Fugas de memoria a tutiplen. Me duele la cabeza, a ver si me das un poco mas de luz
Chaky escribió:Donato escribió:#include <stdio.h>
#include <stdlib.h>
#include "head_tail_list.h"
ptrTail actual=NULL, aux=NULL;
ptrHead anadir(int coordx, int coordy, ptrHead p){
if(p == NULL){
p=(ptrHead) malloc(sizeof(struct Head));
p->first=(ptrTail) malloc(sizeof(struct Tail));
p->numElem=1;
p->first->c.x=coordx;
p->first->c.y=coordy;
p->first->next=NULL;
p->last=p->first;
return p;
}
p->last->next=(ptrTail) malloc(sizeof(struct Tail));
p->last->next->c.x=coordx;
p->last->next->c.y=coordy;
p->last->next->next=NULL;
p->last=p->last->next;
p->numElem++;
return p;
}
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p->first->c.x == coordx && p->first->c.y == coordy){
ptrTail t=p->first;
p->first=p->first->next;
free(t);
}
actual=p->first->next;
aux=p->first;
while(actual != NULL){
if(actual->c.x == coordx && actual->c.y == coordy){
if(actual == p->last){
free(actual);
p->last=aux;
}
else{
aux->next=actual->next;
free(actual);
}
p->numElem--;
}
else
actual=actual->next;
}
return p;
}
void borrarTodo(ptrHead p){
actual=p->first->next;
aux=p->first;
while(actual !=NULL){
free(aux);
aux=actual;
actual=actual->next;
}
free(p);
}
void imprimir(ptrHead p){
int i=0;
ptrTail t=p->first;
printf("El número de nodos es %d\n", p->numElem);
while(t!= NULL){
printf("Nodo %d:\n Coordenada x %d\n Coordenada y %d\n", i, t->c.x, t->c.y);
t=t->next;
i++;
}
}
Ultimos cambios.. Fugas de memoria a tutiplen. Me duele la cabeza, a ver si me das un poco mas de luz
Vamos a ver, seguimos en la funcón borrar. Lo que haces en el caso de que sea el ultimo, esta incompleto, ya que aunq sea el ultimo de la lista, el peniltimo, que ahora es el ultimo, debes de dejarlo apuntando a NULL, ya que si no lo haces, cuando la recorras intetaras acceder a la memoria que ya has borrado. Por otro lado, esto:
else
actual=actual->next;
Si dejas este else ahí, me parece que una vez hallas eliminado, ese else no se va a cumplir, y no va a seguir avanzando en la lista, si dejas ese else, dentro del IF anterior tienes que dejar los puntero preparados para que prosiga el while.
Am casi se me olvida, lo primero que debes comprobar es si el primer elemento es NULL (p->first), porque si lo es, he intentas accerder al p->first->next, te a cascar, lo primero que debes comprbar esque p->first no sea nulo, y si no lo es ya haces todo lo demas.
PD: Por que usas el aux y actual como varibles globales?, no seria mas lógico usarlas como locales en la función?
#include <stdio.h>
#include <stdlib.h>
#include "head_tail_list.h"
ptrHead anadir(int coordx, int coordy, ptrHead p){
if(p == NULL){
p=(ptrHead) malloc(sizeof(struct Head));
p->first=NULL;
p->last=NULL;
p->numElem=0;
}
if(p->first == NULL){
p->first=(ptrTail) malloc(sizeof(struct Tail));
p->numElem=1;
p->first->c.x=coordx;
p->first->c.y=coordy;
p->first->next=NULL;
p->last=p->first;
return p;
}
p->last->next=(ptrTail) malloc(sizeof(struct Tail));
p->last->next->c.x=coordx;
p->last->next->c.y=coordy;
p->last->next->next=NULL;
p->last=p->last->next;
p->numElem++;
return p;
}
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p->first != NULL){
ptrTail actual=NULL, aux=NULL;
if(p->first->c.x == coordx && p->first->c.y == coordy){
ptrTail t=p->first;
p->first=p->first->next;
free(t);
}
actual=p->first->next;
aux=p->first;
while(actual != NULL){
if(actual->c.x == coordx && actual->c.y == coordy){
if(actual == p->last){
free(actual);
p->last=aux;
p->last->next=NULL;
}
else{
aux->next=actual->next;
free(actual);
}
p->numElem--;
}
actual=actual->next;
aux=aux->next;
}
}
return p;
}
void borrarTodo(ptrHead p){
ptrTail actual=NULL, aux=NULL;
actual=p->first->next;
aux=p->first;
while(actual !=NULL){
free(aux);
aux=actual;
actual=actual->next;
}
free(p);
}
void imprimir(ptrHead p){
int i=0;
ptrTail t=p->first;
printf("El número de nodos es %d\n", p->numElem);
while(t!= NULL){
printf("Nodo %d:\n Coordenada x %d\n Coordenada y %d\n", i, t->c.x, t->c.y);
t=t->next;
i++;
}
}
Donato escribió:Chaky escribió:Donato escribió:#include <stdio.h>
#include <stdlib.h>
#include "head_tail_list.h"
ptrTail actual=NULL, aux=NULL;
ptrHead anadir(int coordx, int coordy, ptrHead p){
if(p == NULL){
p=(ptrHead) malloc(sizeof(struct Head));
p->first=(ptrTail) malloc(sizeof(struct Tail));
p->numElem=1;
p->first->c.x=coordx;
p->first->c.y=coordy;
p->first->next=NULL;
p->last=p->first;
return p;
}
p->last->next=(ptrTail) malloc(sizeof(struct Tail));
p->last->next->c.x=coordx;
p->last->next->c.y=coordy;
p->last->next->next=NULL;
p->last=p->last->next;
p->numElem++;
return p;
}
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p->first->c.x == coordx && p->first->c.y == coordy){
ptrTail t=p->first;
p->first=p->first->next;
free(t);
}
actual=p->first->next;
aux=p->first;
while(actual != NULL){
if(actual->c.x == coordx && actual->c.y == coordy){
if(actual == p->last){
free(actual);
p->last=aux;
}
else{
aux->next=actual->next;
free(actual);
}
p->numElem--;
}
else
actual=actual->next;
}
return p;
}
void borrarTodo(ptrHead p){
actual=p->first->next;
aux=p->first;
while(actual !=NULL){
free(aux);
aux=actual;
actual=actual->next;
}
free(p);
}
void imprimir(ptrHead p){
int i=0;
ptrTail t=p->first;
printf("El número de nodos es %d\n", p->numElem);
while(t!= NULL){
printf("Nodo %d:\n Coordenada x %d\n Coordenada y %d\n", i, t->c.x, t->c.y);
t=t->next;
i++;
}
}
Ultimos cambios.. Fugas de memoria a tutiplen. Me duele la cabeza, a ver si me das un poco mas de luz
Vamos a ver, seguimos en la funcón borrar. Lo que haces en el caso de que sea el ultimo, esta incompleto, ya que aunq sea el ultimo de la lista, el peniltimo, que ahora es el ultimo, debes de dejarlo apuntando a NULL, ya que si no lo haces, cuando la recorras intetaras acceder a la memoria que ya has borrado. Por otro lado, esto:
else
actual=actual->next;
Si dejas este else ahí, me parece que una vez hallas eliminado, ese else no se va a cumplir, y no va a seguir avanzando en la lista, si dejas ese else, dentro del IF anterior tienes que dejar los puntero preparados para que prosiga el while.
Am casi se me olvida, lo primero que debes comprobar es si el primer elemento es NULL (p->first), porque si lo es, he intentas accerder al p->first->next, te a cascar, lo primero que debes comprbar esque p->first no sea nulo, y si no lo es ya haces todo lo demas.
PD: Por que usas el aux y actual como varibles globales?, no seria mas lógico usarlas como locales en la función?
Como has dicho que son locales, pues nada, a variable globales xD
Aquí lo nuevo:#include <stdio.h>
#include <stdlib.h>
#include "head_tail_list.h"
ptrHead anadir(int coordx, int coordy, ptrHead p){
if(p == NULL){
p=(ptrHead) malloc(sizeof(struct Head));
p->first=NULL;
p->last=NULL;
p->numElem=0;
}
if(p->first == NULL){
p->first=(ptrTail) malloc(sizeof(struct Tail));
p->numElem=1;
p->first->c.x=coordx;
p->first->c.y=coordy;
p->first->next=NULL;
p->last=p->first;
return p;
}
p->last->next=(ptrTail) malloc(sizeof(struct Tail));
p->last->next->c.x=coordx;
p->last->next->c.y=coordy;
p->last->next->next=NULL;
p->last=p->last->next;
p->numElem++;
return p;
}
ptrHead borrar(int coordx, int coordy, ptrHead p){
if(p->first != NULL){
ptrTail actual=NULL, aux=NULL;
if(p->first->c.x == coordx && p->first->c.y == coordy){
ptrTail t=p->first;
p->first=p->first->next;
free(t);
}
actual=p->first->next;
aux=p->first;
while(actual != NULL){
if(actual->c.x == coordx && actual->c.y == coordy){
if(actual == p->last){
free(actual);
p->last=aux;
p->last->next=NULL;
}
else{
aux->next=actual->next;
free(actual);
}
p->numElem--;
}
actual=actual->next;
aux=aux->next;
}
}
return p;
}
void borrarTodo(ptrHead p){
ptrTail actual=NULL, aux=NULL;
actual=p->first->next;
aux=p->first;
while(actual !=NULL){
free(aux);
aux=actual;
actual=actual->next;
}
free(p);
}
void imprimir(ptrHead p){
int i=0;
ptrTail t=p->first;
printf("El número de nodos es %d\n", p->numElem);
while(t!= NULL){
printf("Nodo %d:\n Coordenada x %d\n Coordenada y %d\n", i, t->c.x, t->c.y);
t=t->next;
i++;
}
}
He mejorado el añadir y el borrar. Aun sigue habiendo fugas de memoria en el borrar pero el caso es que ya borra bien.
Ferdy escribió:Estoy ecándole un vistazo y lo primero que veo es que borrarTodo no borra bien una lista de un solo elemento.
Actualizaré el post si veo cosas raras.
- ferdy
Ferdy escribió:borrar tambien falla si quieres borrar el único elemento de la lista.
borrar no actualiza bien numElements si borra el primer elemento de una lista.
A borrar no le gusta que le pases una lista inexistente (p == NULL).
borrarTodo realmente no funciona. Siempre se deja un elemento sin borrar. Da igual la longitud de la lista.
En fin... que a repasar el código o a estudiar un poco más. Un libro muy didáctico para estas cosas es "Mastering Algorithms with C" de Kyle Loudon.
- ferdy
PS: ¿Quién es tu compañero de prácticas?