2017-05-18 52 views
0

所以,我一直試圖做一個哈希表的數據結構類和我不斷收到異常「讀訪問衝突:我不能讓我的頭此異常各地:讀訪問衝突

#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

在函數'adaugareEchipa'中調用'creareHashTable'。但是你如何處理它返回的'hashtable'結構呢? –

+1

您的代碼不完整,請顯示您實際編譯的代碼。 –

+0

_I在函數中加入異常以添加到列表中,while。我嘗試將一個類型的項目組添加到list_中:OK,哪個函數? –

回答

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,在這種情況下會導致崩潰。更好

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); 

此外,您的哈希函數返回一個無效的:

移動電話外的+1 strlen指數。包含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; 
} 
+0

現在它工作。非常感謝你 ! –