所以,我一直在尝试为数据结构类创建一个哈希表,并且我一直得到异常“读取访问冲突:
#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
(它应该将一个项添加到列表中)中获得异常。
我尝试将一个类型团队的项目添加到列表中。
答案 0 :(得分:0)
您正在echipaNoua
和DeepCopy
中阅读数组末尾:
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
而不是单独调用malloc
和strcpy
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;
}