PI-ITBA / 2024_01

8 stars 0 forks source link

elemCountADT #373

Closed sratto0 closed 3 months ago

sratto0 commented 3 months ago

Buen dia, queria saber si me podian ayudar a encontrar el error en el codigo, pasa el assert pero despues del "OK!", me tira memory leaks el sanitize en el addRec y no se como resolverlo

typedef struct node{
    elemtype elem;
    size_t cant;
    struct node *tail;
}TNode;

typedef TNode *TList;

typedef struct elemCountCDT{
    compare cmp;
    TList first;
    TList iter;
    size_t cantDist;
}elemCountCDT;

elemCountADT newElemCount(compare cmp){
    elemCountADT new=calloc(1, sizeof(elemCountCDT));
    new->cmp=cmp;
    return new;
}

static TList addRec(TList l, compare cmp, int *flag, elemtype elem, int *cant){
    if(l==NULL || cmp(l->elem, elem)>0){
        TList aux=malloc(sizeof(TNode));
        aux->elem=elem;
        aux->tail=l;
        *flag=1;
        aux->cant=1;
        *cant=aux->cant;
        return aux;
    }
    if(cmp(l->elem, elem)==0){
        l->cant++;
        *cant=l->cant;
        return l;
    }
    l->tail=addRec(l->tail, cmp, flag, elem, cant);
    return l;
}

long unsigned int countElem(elemCountADT elemCountAdt, elemtype elem){
    int flag=0, cant=0;
    elemCountAdt->first=addRec(elemCountAdt->first, elemCountAdt->cmp, &flag, elem, &cant);
    if(flag){
        elemCountAdt->cantDist++;
    }
    return cant;
}

long unsigned int distinctElems(elemCountADT elemCountAdt){
    return elemCountAdt->cantDist;
}

void toBegin(elemCountADT elemCountAdt){
    elemCountAdt->iter=elemCountAdt->first;
}

long unsigned int hasNext(elemCountADT elemCountAdt){
    return elemCountAdt->iter!=NULL;
}

elemtype next(elemCountADT elemCountAdt, long unsigned int * count){
    if(!hasNext(elemCountAdt))
        exit(1);
    elemtype ans=elemCountAdt->iter->elem;
    *count=elemCountAdt->iter->cant;
    elemCountAdt->iter=elemCountAdt->iter->tail;
    return ans;
}

static void freeRec(TList l){
    if(l==NULL)
        return ;
    free(l->tail);
}

void freeElemCount(elemCountADT elemCountAdt){
    freeRec(elemCountAdt->first);
    freeRec(elemCountAdt->iter);
    free(elemCountAdt);
}

int cmpInts(int a, int b) {
return a - b;
}
int
main(void) {
elemCountADT ecADT = newElemCount(cmpInts);
assert(countElem(ecADT, 10) == 1);
assert(countElem(ecADT, 5+5) == 2);
assert(distinctElems(ecADT) == 1);
assert(countElem(ecADT, 5) == 1);
assert(countElem(ecADT, 10) == 3);
assert(countElem(ecADT, 5) == 2);
assert(countElem(ecADT, 30) == 1);
assert(distinctElems(ecADT) == 3);
// Se itera por todos los elementos
size_t aux;
toBegin(ecADT);
assert(hasNext(ecADT) == 1);
assert(next(ecADT, &aux) == 5 && aux == 2);
assert(hasNext(ecADT) == 1);
assert(next(ecADT, &aux) == 10 && aux == 3);
assert(next(ecADT, &aux) == 30 && aux == 1);
assert(hasNext(ecADT) == 0);
freeElemCount(ecADT);
puts("OK!");
return 0;
}

El error:


OK!

=================================================================
==281865==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7fddb9f47887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x561e0f523437 in addRec /home/sofi/PI/R2/2023_1C/ej3.c:29
    #2 0x561e0f52367d in addRec /home/sofi/PI/R2/2023_1C/ej3.c:42
    #3 0x561e0f52367d in addRec /home/sofi/PI/R2/2023_1C/ej3.c:42
    #4 0x561e0f523844 in countElem /home/sofi/PI/R2/2023_1C/ej3.c:48
    #5 0x561e0f523ef8 in main /home/sofi/PI/R2/2023_1C/ej3.c:100
    #6 0x7fddb9bacd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7fddb9f47887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x561e0f523437 in addRec /home/sofi/PI/R2/2023_1C/ej3.c:29
    #2 0x561e0f523844 in countElem /home/sofi/PI/R2/2023_1C/ej3.c:48
    #3 0x561e0f523e23 in main /home/sofi/PI/R2/2023_1C/ej3.c:97
    #4 0x7fddb9bacd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)

SUMMARY: AddressSanitizer: 48 byte(s) leaked in 2 allocation(s).
marcelogarberoglio commented 3 months ago

¿no estás liberando de más? freeRec(elemCountAdt->first); freeRec(elemCountAdt->iter);

Pero además te dice que falta liberar lo que pediste en la línea, no estás liberando el primer nodo de cada lista. Compará el freeRec con el típico que hicimos varias veces para listas

sratto0 commented 3 months ago

ahi me funciono, gracias!!