PI-ITBA / 2024_02

Consultas 2C 2024
4 stars 0 forks source link

MuseumTicketADT #169

Open Alang04 opened 4 hours ago

Alang04 commented 4 hours ago

Hola buenas cuando corro el codigo me dice que tengo memory leak y no encuentro el error

#include "museumTicketADT.h"
#include <strings.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define YEAR 366
#define NOVALIDDATE(s) ((0>=s) || (YEAR<s)) 

typedef struct Node{
  char * visitor;
  struct Node * tail;
}tNode;

typedef tNode * tList;

typedef struct day{
  size_t sizeday;
  tList iter;
  tList first;
}tDay;

typedef tDay * DayList;

typedef struct museumTicketCDT{
  tDay days[YEAR];
  size_t sizeYear;     
}museumTicketCDT;

int
main(void) {
    // Reserva los recursos para administrar las ventas de tickets
    museumTicketADT museum = newMuseumTicket();

    // Se registra un ticket para que John visite el museo el día 4 del año
    assert(addTicket(museum, 4, "John") == 1);
    // Los siguientes fallan porque John ya cuenta con un ticket para el día 4 del año
    assert(addTicket(museum, 4, "John") == 0);
    assert(addTicket(museum, 4, "JOHN") == 0);
    assert(addTicket(museum, 4, "john") == 0);

    // Falla porque John ya cuenta con un ticket para visitar el museo el día 4 del año
    assert(addTicket(museum, 4, "John") == 0);
    // Se registra un ticket para que John visite el museo el día 360 del año
    assert(addTicket(museum, 360, "John") == 1);

    // Falla porque el día del año es igual a 0
    assert(addTicket(museum, 0, "Katherine") == 0);
    // Falla porque el día del año es mayor a 366
    assert(addTicket(museum, 367, "Katherine") == 0);

    assert(addTicket(museum, 4, "Paul") == 2);
    assert(addTicket(museum, 4, "Ariel") == 3);
    assert(addTicket(museum, 360, "Brenda") == 2);

    // Se inicializa el iterador para el día 4 del año
    toBeginByDay(museum, 4);
    // Quedan visitantes por recorrer para el día 4 del año
    assert(hasNextByDay(museum, 4) == 1);
    // Se obtiene el primer visitante para el día 4 del año en orden alfabético
    assert(strcmp(nextByDay(museum, 4), "Ariel") == 0);

    toBeginByDay(museum, 360);
    // Se obtiene el primer visitante para el día 360 del año en orden alfabético
    assert(hasNextByDay(museum, 360) == 1);
    assert(strcmp(nextByDay(museum, 360), "Brenda") == 0);

    assert(hasNextByDay(museum, 4) == 1);
    // Se obtiene el segundo visitante para el día 4 del año en orden alfabético
    assert(strcmp(nextByDay(museum, 4), "John") == 0);
    assert(hasNextByDay(museum, 360) == 1);
    // Se obtiene el segundo visitante para el día 360 del año en orden alfabético
    assert(strcmp(nextByDay(museum, 360), "John") == 0);

    assert(hasNextByDay(museum, 4) == 1);
    assert(strcmp(nextByDay(museum, 4), "Paul") == 0);
    // No quedan más visitantes por recorrer para el día 4 del año
    assert(hasNextByDay(museum, 4) == 0);
    // No quedan más visitantes por recorrer para el día 360 del año
    assert(hasNextByDay(museum, 360) == 0);

    // Se obtiene la cantidad de tickets para el día 4 del año
    assert(dayTickets(museum, 4) == 3);
    assert(dayTickets(museum, 360) == 2);
    assert(dayTickets(museum, 15) == 0);

    // Se obtiene la cantidad total de tickets (todos los días del año)
    assert(yearTickets(museum) == 5);

    // Libera los recursos utilizados para administrar las ventas de tickets
    freeMuseumTicket(museum);

    puts("OK!");
    return 0;
}

museumTicketADT newMuseumTicket(void){
    return calloc(1,sizeof(museumTicketCDT));
}
static tList addTicketRec(tList l,char *visitor,int * flag){
  int c;
  if(l==NULL || (c=strcasecmp(l->visitor, visitor ) )> 0 ){
    tList new=malloc(sizeof(*new));
    new->tail=l;
    //new->visitor= visitor;
    new->visitor=malloc(strlen(visitor)+1);
    strcpy(new->visitor,visitor);
    *flag=1;
    return new;
  }
  if(c==0){
    return l;
  }
  l->tail=addTicketRec(l->tail,visitor,flag);
  return l;
}

int addTicket(museumTicketADT museumTicketADT, size_t dayOfYear,  char * visitor){
  if(NOVALIDDATE(dayOfYear) ){
    return 0;
  }
  int flag=0;
  museumTicketADT->days[dayOfYear-1].first = addTicketRec(museumTicketADT->days[dayOfYear-1].first,visitor,&flag);
  if(!flag){
    return 0;
  }
  museumTicketADT->days[dayOfYear-1].sizeday++;
  museumTicketADT->sizeYear++;
  return museumTicketADT->days[dayOfYear-1].sizeday;
}

int dayTickets(const museumTicketADT museumTicketADT, size_t dayOfYear){
  if(NOVALIDDATE(dayOfYear)){
    return -1;
  }
  return museumTicketADT->days[dayOfYear-1].sizeday;
}

int yearTickets(const museumTicketADT museumTicketADT){
  return museumTicketADT->sizeYear;
}

void toBeginByDay(museumTicketADT museumTicketADT, size_t dayOfYear){
  if(NOVALIDDATE(dayOfYear)){
    exit(1);
  }
  museumTicketADT->days[dayOfYear-1].iter=museumTicketADT->days[dayOfYear-1].first;
  return;
}

size_t hasNextByDay(museumTicketADT museumTicketADT, size_t dayOfYear){
  if(NOVALIDDATE(dayOfYear)){
    exit(1);
  }
  return museumTicketADT->days[dayOfYear-1].iter != NULL;
}

static void freeMuseumTicketRec(tList l){
  if(l == NULL){
    return;
  }
  freeMuseumTicketRec(l->tail);
  free(l->visitor);
  free(l);
  return;
}

void freeMuseumTicket(museumTicketADT museumTicketADT){
  for(int i=0;i<YEAR;i++){
    freeMuseumTicketRec(museumTicketADT->days[i].first);
    free(museumTicketADT->days[i].iter);
  }
  free(museumTicketADT);
  return;
}

char * nextByDay(museumTicketADT museumTicketADT, size_t dayOfYear){
  if(!hasNextByDay(museumTicketADT,dayOfYear) || NOVALIDDATE(dayOfYear)){
    exit(1);
  }
  char * copy=malloc(strlen(museumTicketADT->days[dayOfYear-1].iter->visitor)+1);
  strcpy(copy,museumTicketADT->days[dayOfYear-1].iter->visitor);
  museumTicketADT->days[dayOfYear-1].iter=museumTicketADT->days[dayOfYear-1].iter->tail;
  return copy;
}

image image image

ImNotGone commented 4 hours ago

Estas devolviendo un puntero del heap en el next, que el test no debe liberar. En el .h te pedian que devuelvas una copia?

Alang04 commented 4 hours ago

No lo pedia, entonces no hago la copia solo le retorno mi puntero ? O podria liberarlo en la funcion free?

ImNotGone commented 4 hours ago

Leyendo el test al darte cuenta que no libera el puntero, se da a entender que deberias retornar sin copia. si. Liberarlo no podrias pq perdes la referencia, no lo guardas en ningun lugar de tu adt solo se lo das al usuario.

Alang04 commented 4 hours ago

Ok muchas gracias