PI-ITBA / 2024_01

9 stars 0 forks source link

airportADT #372

Closed sratto0 closed 1 week ago

sratto0 commented 1 week ago

Buens tardes, queria saber si me podian ayudar a encontrar el error en el codigo, no me pasa el assert, y me tira que hay un error en pendingFlights

#define BLOCK 10

typedef struct node {
    char *elem;
    struct node *tail;
}TNode;

typedef TNode*TList;

typedef struct pistas{
    TList first;
    size_t cant_planes;
    TList last;
}pistas;

typedef struct airportCDT{
    pistas *pista;
    size_t dim;
    size_t cant_pistas;
    char *occuppied;
}airportCDT;

airportADT newAirport(void){
    return calloc(1, sizeof(airportCDT));
}

int addRunway(airportADT airportAdt, size_t runwayId){
    if(airportAdt->dim<runwayId){
        airportAdt->pista=realloc(airportAdt->pista, (runwayId)*sizeof(pistas));
        airportAdt->occuppied=realloc(airportAdt->occuppied, (runwayId)*sizeof(char));
        for(int i=airportAdt->dim;i<runwayId;i++){
            airportAdt->pista[i].cant_planes=0;
            airportAdt->pista[i].first=NULL;
            airportAdt->pista[i].last=NULL;
            airportAdt->occuppied[i]=0;
        }
        airportAdt->dim=runwayId;
    }
    if(runwayId==0 || airportAdt->occuppied[runwayId-1])
        return -1;
    airportAdt->occuppied[runwayId-1]=1;
    airportAdt->cant_pistas++;
    return airportAdt->cant_pistas;
}

static char *copy(const char *registration){
    char *ans=NULL;
    int i;
    for(i=0;registration[i];i++){
        if(i%BLOCK==0)
            ans=realloc(ans, (i+BLOCK)*sizeof(char));
        ans[i]=registration[i];
    }
    if(ans!=NULL){
        ans=realloc(ans, (i+1)*sizeof(char));
        ans[i]=0;
    }
    return ans;
}

int addPlaneToRunway(airportADT airportAdt, size_t runwayId, const char * registration){
    if(airportAdt->dim<runwayId || airportAdt->occuppied[runwayId-1]==0){
        return -1;
    }
    TList aux=malloc(sizeof(TNode));
    aux->elem=copy(registration);
    aux->tail=NULL;
    if(airportAdt->pista[runwayId-1].cant_planes==0){
        airportAdt->pista[runwayId-1].first=aux;
    }else{
        airportAdt->pista[runwayId-1].last->elem=aux->elem;
    }
    airportAdt->pista[runwayId-1].last=aux;
    airportAdt->pista[runwayId-1].cant_planes++;
    return airportAdt->pista[runwayId-1].cant_planes;
}

char * takeOff(airportADT airportAdt, size_t runwayId){
    char *aux=NULL;
    if(airportAdt->cant_pistas==0 || airportAdt->occuppied[runwayId-1]==0){
        return aux;
    }
    aux=realloc(aux, strlen(airportAdt->pista[runwayId-1].first->elem)*sizeof(char));
    strcpy(aux,airportAdt->pista[runwayId-1].first->elem);
    airportAdt->pista[runwayId-1].first=airportAdt->pista[runwayId-1].first->tail;
    airportAdt->pista[runwayId-1].cant_planes--;
    return aux;
}

char ** pendingFlights(airportADT airportAdt, size_t runwayId){
    if(airportAdt->cant_pistas==0 || airportAdt->dim<runwayId || airportAdt->occuppied[runwayId-1]==0 || airportAdt->pista[runwayId-1].cant_planes==0)
        return NULL;
    int i=airportAdt->pista[runwayId-1].cant_planes-1;
    char **vec=malloc((airportAdt->pista[runwayId-1].cant_planes+1)*sizeof(char *));
    //vec[airportAdt->pista[runwayId-1].cant_planes-1]=malloc(sizeof(char));
    vec[airportAdt->pista[runwayId-1].cant_planes-1]="";
    while(airportAdt->pista[runwayId-1].first!=NULL){
        //vec[i]=malloc((strlen(airportAdt->pista[runwayId-1].first->elem)+1)*sizeof(char));
        strcpy(vec[i],airportAdt->pista[runwayId-1].first->elem);
        i--;
        airportAdt->pista[runwayId-1].first=airportAdt->pista[runwayId-1].first->tail;
    }
    return vec;
}
static void freeRec(TList l){
    if(l==NULL)
        return ;
    free(l->tail);
    free(l);
}

void freeAirport(airportADT airportAdt){
    for(int i=0;i<airportAdt->dim;i++){
        if(airportAdt->pista[i].last==NULL){
            freeRec(airportAdt->pista[i].first);
        }
    }
    free(airportAdt->pista);
    free(airportAdt);
}

int
main(void) {
// Crea un sistema sin pistas
airportADT airportAdt = newAirport();
// Agrega la pista con el id 5
assert(addRunway(airportAdt, 5) == 1);
assert(addRunway(airportAdt, 1) == 2);
// Falla porque ya existe una pista con el id 5
assert(addRunway(airportAdt, 5) == -1);
// Falla porque no es válida la pista cero
assert(addRunway(airportAdt, 0) == -1);
// Agrega al final de la pista de id 5 al avión de matrícula AR01 y será
// el primero en despegar
char aux[20] = "AR01";
assert(addPlaneToRunway(airportAdt, 5, aux) == 1);
// Agrega al final de la pista de id 5 al avión de matrícula AC91 y será
// el segundo en despegar
strcpy(aux, "AC91");
assert(addPlaneToRunway(airportAdt, 5, aux) == 2);
strcpy(aux, "AC92");
assert(addPlaneToRunway(airportAdt, 5, aux) == 3);
// Obtiene los aviones por despegar de la pista de id 5 en orden inverso al
// orden de despegue
char ** aux2 = pendingFlights(airportAdt, 5);
assert(!strcmp(aux2[0], "AC92"));
assert(!strcmp(aux2[1], "AC91"));
assert(!strcmp(aux2[2], "AR01"));
assert(!strcmp(aux2[3], ""));
free(aux2);
// Despega el primer avión de la pista de id 5
assert(!strcmp(takeOff(airportAdt, 5), "AR01"));
assert(!strcmp(takeOff(airportAdt, 5), "AC91"));
assert(!strcmp(takeOff(airportAdt, 5), "AC92"));
// Ya no quedan aviones por despegar en la pista de id 5
assert(takeOff(airportAdt, 5) == NULL);
// No existe la pista 3
assert(takeOff(airportAdt, 3) == NULL);
// No se puede agregar un avión a una pista que no existe
assert(addPlaneToRunway(airportAdt, 3, "FL91") == -1);
// No se puede agregar un avión a una pista que no existe
assert(pendingFlights(airportAdt, 3) == NULL);
freeAirport(airportAdt);
puts("Despegue exitoso!");
return 0;
}

El error:


=================================================================
==174869==ERROR: AddressSanitizer: global-buffer-overflow on address 0x5645fdcdd021 at pc 0x7f0e8ce5c4bf bp 0x7fffef4a5320 sp 0x7fffef4a4ac8
WRITE of size 5 at 0x5645fdcdd021 thread T0
    #0 0x7f0e8ce5c4be in __interceptor_strcpy ../../../../src/libsanitizer/asan/asan_interceptors.cpp:440
    #1 0x5645fdcdc401 in pendingFlights /home/sofi/PI/R2/2023_1C/ej1.c:106
    #2 0x5645fdcdca2e in main /home/sofi/PI/R2/2023_1C/ej1.c:152
    #3 0x7f0e8cb21d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
    #4 0x7f0e8cb21e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f)
    #5 0x5645fdcdb324 in _start (/home/sofi/PI/R2/2023_1C/ej1+0x2324)

0x5645fdcdd021 is located 0 bytes to the right of global variable '*.LC0' defined in 'ej1.c' (0x5645fdcdd020) of size 1
  '*.LC0' is ascii string ''
SUMMARY: AddressSanitizer: global-buffer-overflow ../../../../src/libsanitizer/asan/asan_interceptors.cpp:440 in __interceptor_strcpy
Shadow bytes around the buggy address:
  0x0ac93fb939b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac93fb939c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac93fb939d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac93fb939e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ac93fb939f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0ac93fb93a00: 00 00 00 00[01]f9 f9 f9 f9 f9 f9 f9 00 00 00 00
  0x0ac93fb93a10: 06 f9 f9 f9 f9 f9 f9 f9 00 00 00 06 f9 f9 f9 f9
  0x0ac93fb93a20: 00 00 00 06 f9 f9 f9 f9 00 00 00 07 f9 f9 f9 f9
  0x0ac93fb93a30: 00 00 00 07 f9 f9 f9 f9 00 00 00 00 00 02 f9 f9
  0x0ac93fb93a40: f9 f9 f9 f9 05 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
  0x0ac93fb93a50: 00 02 f9 f9 f9 f9 f9 f9 05 f9 f9 f9 f9 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==174869==ABORTING
marcelogarberoglio commented 1 week ago

no es que no pase el assert, te esá dando un error de acceso a memoria inválida, en la línea 106 de ej1.c ¿cuál es esa línea? Si te devuelve un char*o char** que no coincide con lo que tiene que dar, fijate de agregarle printfs, para comparar lo que da con lo que debería dar.

sratto0 commented 1 week ago

la linea 106 es

 strcpy(vec[i],airportAdt->pista[runwayId-1].first->elem);
marcelogarberoglio commented 1 week ago

sumale 1 al realloc