【问题标题】:Heap corruption detected after normal block when calling free()调用 free() 时在正常块后检测到堆损坏
【发布时间】:2020-03-23 18:41:14
【问题描述】:
#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);


}

大家好,我尝试了所有可能的方法来调试这个堆栈数据结构,但最终还是无处可去,你能告诉我我写的代码有什么问题吗?

简短的见解:当我调用 free(o.denumire) 时它会中断,这是我从堆栈中弹出的一个对象,它是一个浅拷贝,但地址应该已被传输,因此内存相应地被释放。

感谢您的宝贵时间。

【问题讨论】:

  • C++ 还是 C?选择一种语言。您的代码基本上是 C,但它不能编译为 C,因为您在引用 Oras 时没有使用 struct。 C++ 不仅仅是带有一些额外特性的 C。与 C 相比,用 C++ 编写代码的方式存在显着差异。

标签: c visual-studio


【解决方案1】:

这里

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

应该是

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

sizeof(strlen(...) + 1) 等于sizeof(size_t),因为strlen 返回一个size_tsizeof(size_t) 可能总是 4 或 8,具体取决于您的平台。

【讨论】:

  • 天哪,谢谢约翰,愚蠢的错字!一切顺利,再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
  • 2023-03-21
  • 1970-01-01
  • 2020-08-02
  • 2021-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多