Heap corruption detected after normal block when calling free()

#include<stdlib.h>
#include<stdio.h>
#include<string.h>

struct Oras
{
    char* denumire;
    int nrLocuitori;
    float suprafata;

};

Oras initOras(const char* denumire, int nrLoc, float suprafata) {
    Oras o;
    o.denumire = (char*)malloc(sizeof(strlen(denumire) + 1));
    strcpy(o.denumire, denumire);
    o.nrLocuitori = nrLoc;
    o.suprafata = suprafata;
    return o;
}

void afisareOras(Oras o) {
    printf("Orasul %s are %d loc. si o supraf. de %5.2f mp \n", o.denumire, o.nrLocuitori, o.suprafata);
}

struct Nod {
    Oras info;
    Nod* next;
};

void push(Nod*& stiva, Oras o) {
    Nod* nou = (Nod*)malloc(sizeof(Nod));
    nou->info = o;
    nou->next = NULL;
    if (stiva) {
        Nod* aux = stiva;
        while (aux->next) {
            aux = aux->next;
        }
        aux->next = nou;
    }
    else {
        stiva = nou;
    }
}

Oras pop(Nod*& stiva) {
    if (stiva) {
        Nod* copie = stiva;
        while (copie->next && copie->next->next) {
            copie = copie->next;
        }
        if (copie->next) {
            Oras o = copie->next->info;
            free(copie->next);
            copie->next = NULL;
            return o;
        }
        else {
            Oras o = copie->info;
            free(copie);
            stiva = NULL;
            return o;
        }
    }
    else {
        throw "Nu exista stiva!";
    }
}

int nrTotalLocuitori(Nod*& stiva) {
    Nod* copie = NULL;
    int nrTotalLocuitori = 0;
    while (stiva) {
        Oras o;
        o = pop(stiva);
        nrTotalLocuitori += o.nrLocuitori;
        push(copie, o);
    }
    while (copie) {
        push(stiva, pop(copie));
    }
    return nrTotalLocuitori;
}

void stergereOrasDupaNume(Nod*& stiva, const char* nume) {
    Nod* copie = NULL;
    int ok = 1;
    while (stiva && ok) {
        Oras o = pop(stiva);
        if (strcmp(o.denumire, nume) == 0) {
            printf("Adresa pointer : %d\n", o.denumire);
            //printf("Adresa pointer : %d\n", (*pointer).denumire);
            //free(o.denumire);
            ok = 0;
        }
        else {
            push(copie, o);
        }
    }
    while (copie) {
        push(stiva, pop(copie));
    }
}

void afisareStiva(Nod*& stiva) {
    while (stiva) {
        afisareOras(pop(stiva));
    }
}

void main() {
    Nod* stiva = NULL;
    push(stiva, initOras("Bucuresti", 2000, 4.56));
    push(stiva, initOras("Craiova", 5969, 46));
    push(stiva, initOras("Cluj", 12367, 120));

    //afisareOras(pop(stiva));
    printf("Nr. total locuitori : %d\n", nrTotalLocuitori(stiva));
    stergereOrasDupaNume(stiva, "Bucuresti");
    afisareStiva(stiva);


}

Hello everyone, I tried every way possible to debug this stack data structure but I ended up nowhere, could you please show me what's wrong with the code I wrote?

Short insight : It breaks when I call free(o.denumire) this is an object that I pop from the stack and it's a shallow copy but the addresses should have been transfered and thus the memory freed accordingly.

Thank you for your time.

Upvotes: 0

Views: 672

Answers (1)

john
john

Reputation: 87959

Here

o.denumire = (char*)malloc(sizeof(strlen(denumire) + 1));
strcpy(o.denumire, denumire);

should be

o.denumire = (char*)malloc(strlen(denumire) + 1);
strcpy(o.denumire, denumire);

sizeof(strlen(...) + 1) equals sizeof(size_t) because strlen returns a size_t. And sizeof(size_t) is likely always 4 or 8, depending on your platform.

Upvotes: 3

Related Questions