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

时间:2017-05-18 15:12:20

标签: c++ exception

所以,我一直在尝试为数据结构类创建一个哈希表,并且我一直得到异常“读取访问冲突:

#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(它应该将一个项添加到列表中)中获得异常。 我尝试将一个类型团队的项目添加到列表中。

1 个答案:

答案 0 :(得分:0)

您正在echipaNouaDeepCopy中阅读数组末尾:

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

不是在缓冲区的长度上加1,而是在缓冲区的地址中加1。这会在数组结束之后产生一个地址,这是strlen开始读取的地方。这会调用undefined behavior,在这种情况下会导致崩溃。

将+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是超过数组末尾的索引。这也会调用未定义的行为。

更改函数以返回适当范围内的索引。

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