我无法理解此异常:读取访问冲突

I can't get my head around this exception: read access violation

本文关键字:异常 读取 访问冲突      更新时间:2023-10-16

所以,我一直在尝试为数据结构类制作一个哈希表,但我不断收到异常"读取访问冲突:

#include <iostream>
#include <fstream>
using namespace std;
struct Echipa{
    char* nume;
    int victorii;
    int infrangeri;
    int egaluri;
    int puncte;
};
struct nod {
    Echipa ech;
    nod*urm;
};
Echipa echipaNoua() {
    Echipa e;
    e = { "",0,0,0,0 };
    char buffer[30];
    printf("Nume echipa: ");scanf("%s", buffer);printf("n");
    e.nume = (char*)malloc(sizeof(char)*strlen(buffer + 1));
    strcpy(e.nume, buffer);
    printf("Victorii: ");scanf("%d", &e.victorii);printf("n");
    printf("Egaluri: ");scanf("%d",&e.egaluri);printf("n");
    printf("Infrangeri: ");scanf("%d", &e.infrangeri);printf("n");
    e.puncte = 3 * e.victorii + e.egaluri;
    return e;
}
void afisareEchipa(Echipa e)
{
    printf("%s - %d - %d - %d - %d n", e.nume, e.victorii, e.egaluri, e.infrangeri, e.puncte);
}

Echipa DeepCopy(Echipa e) {
    Echipa e1 = { "",0,0,0,0 };
    e1.nume = (char*)malloc(sizeof(char)*strlen(e.nume + 1));
    strcpy(e1.nume, e.nume);
    e1.victorii = e.victorii;
    e1.infrangeri = e.infrangeri;
    e1.egaluri = e.egaluri;
    e1.puncte = e.puncte;
    return e1;
}
struct hashtable {
    int dimen;
    nod** vec;
};
hashtable creareHashTable(int dim)
{
    hashtable ht;
    ht.vec = (nod**)malloc(sizeof(nod*)*dim);
    for (int i = 0;i < dim;i++)
        ht.vec[i] = NULL;
    ht.dimen = dim;
    return ht;
}

int functiehash(int nrPuncte)
{
    if (nrPuncte < 30) return 4;
    else if (nrPuncte < 50) return 3;
    else if (nrPuncte < 70) return 2;
    else return 1;
}
struct Coada {
    nod* inceput;
    nod* sfarsit;
};
nod* inserareLS(nod* cap, Echipa e)
{
    nod* nou = (nod*)malloc(sizeof(nod));
    nou->ech = DeepCopy(e);
    nou->urm = NULL;
    if (cap) {
        nod* aux = (nod*)malloc(sizeof(nod));
        aux = cap;
        while (aux->urm)
        {
            aux = aux->urm;
        }
        aux->urm = nou;
    }
    else {
        cap = nou;
    }
    return cap;
}
hashtable adaugareEchipa(hashtable ht, Echipa e)
{
    if (ht.vec == NULL)
        ht=creareHashTable(4);
    int poz = functiehash(e.puncte);
    ht.vec[poz] = inserareLS(ht.vec[poz], e);
    return ht;
}
void afisareLS(nod* cap){
    while (cap)
    {
        afisareEchipa(cap->ech);
        cap = cap->urm;
    }
}
Coada adaugareCoada(Coada c, Echipa e) {
    nod* nou;
    if (!c.inceput)
    {
        c.inceput = (nod*)malloc(sizeof(nod));
        c.sfarsit = (nod*)malloc(sizeof(nod));
        c.inceput->ech = DeepCopy(e);
        c.inceput->urm = NULL;
        c.sfarsit = c.inceput;
    }
    else {
        nou = (nod*)malloc(sizeof(nod));
        c.sfarsit->urm = nou;
        nou->ech = DeepCopy(e);
        c.sfarsit = nou;
        c.sfarsit->urm = NULL;
    }
    return c;
}
void afisareCoada(Coada *c)
{
    if (!c->inceput)
    {
        printf("Nu avem ce afisa, coada este goala!");
    }
    else
    {
        nod*nou=c->inceput;
        while (nou)
        {
            afisareEchipa(nou->ech);
            nou = nou->urm;
        }
    }
}
void stergeDinCoada(Coada* c)
{
    nod*n;
    if (!c->inceput)
        cout << "Coada este goala, nu avem ce elimina!n";
    else {
        n = c->inceput;
        c->inceput = c->inceput->urm;
        free(n);
    }
}
void afisareHashTable(hashtable ht)
{
    for (int i = 0;i < ht.dimen;i++)
    {
        if (i == 0) printf("Echipe cu un sezon foarte bun:n");
        if (i == 1) printf("Echipe cu un sezon bun:n");
        if (i == 2) printf("Echipe cu un sezon slab:n");
        if (i == 3) printf("Echipe cu un sezon foarte slab:n");
        afisareLS(ht.vec[i]);
    }
}
void main()
{
    /*Echipa e = echipaNoua();
    nod* n1 = NULL;
    nod*n2 = NULL;
    Coada c = {n1,n2};
    c=adaugareCoada(c,e);
    c = adaugareCoada(c, e1);
    c = adaugareCoada(c, e2);
    afisareCoada(&c);
    stergeDinCoada(&c);
    afisareCoada(&c);*/
    Echipa e1 = echipaNoua();
    Echipa e2 = echipaNoua();
    Echipa e3 = echipaNoua();
    hashtable ht = creareHashTable(4);
    ht = adaugareEchipa(ht,e1);
    ht = adaugareEchipa(ht, e2);
    ht = adaugareEchipa(ht, e3);
    afisareHashTable(ht);
    system("pause");
 }

我在函数 inserareLS(应该将项目添加到列表中(中得到异常。我尝试将团队类型的项目添加到列表中。

您正在阅读数组的末尾,echipaNouaDeepCopy

e.nume = (char*)malloc(sizeof(char)*strlen(buffer + 1));
...
e1.nume = (char*)malloc(sizeof(char)*strlen(e.nume + 1));
不是在缓冲区的长度上加 1,

而是在缓冲区的地址上加 1。 这会导致数组末尾之后的地址,strlen从该地址开始读取。 这将调用未定义的行为,在这种情况下会导致崩溃。

将呼叫外的 +1 移到strlen

e.nume = (char*)malloc(sizeof(char)*strlen(buffer) + 1);
...
e1.nume = (char*)malloc(sizeof(char)*strlen(e.nume) + 1);

更好的是,使用 strdup 而不是单独调用 mallocstrcpy

e.nume = strdup(buffer);
...
e1.nume = strdup(e.nume);

此外,您的哈希函数返回无效索引。 包含 4 个元素的数组的索引为 0 到 3,但您返回的值从 1 到 4。 读取具有 4 个元素的数组的索引 4 是数组末尾的 1。 这也调用未定义的行为。

更改函数以返回正确范围内的索引。

int functiehash(int nrPuncte)
{
    if (nrPuncte < 30) return 3;
    else if (nrPuncte < 50) return 2;
    else if (nrPuncte < 70) return 1;
    else return 0;
}