2014-12-21 17 views
5

tarafından oluşturulan, bu yüzden küresel olması gerekiyor ve benim başlık dosyaları birinde bunu beyan edilmiştirBaşlatılmamış değer bir karma tablosu kullanılarak kelimelik bir sözlük uygulamak çalışıyorum bir yığın ayırma

extern node** dictionary; 
düğüm fonksiyonları bir sözlük bildirimi içeren başlığını da tanımlandığı gibi olduğu bir dosyada

typedef struct node 
{ 
    char* word; 
    struct node* next; 
} node; 

O ve

ayrıca en

node** dictionary; 
eklenecek

Sonra aslında sözlüğü ilk karma tablosunu yapacak bağlantılı listeler için bellek ayrılamadı yükleyen işlevinde

bool load(const char* dict_file) 
{ 
    dictionary = malloc(sizeof(node*) * LISTS); 

    FILE* dict = fopen(dict_file, "r"); 

    if(dict == NULL) 
     return false; 

    char buffer[MAX_LEN + 2]; 

    size_dict = 0; 

    while(fgets(buffer, MAX_LEN + 2, dict) != NULL) 
    { 
     node* new_node = malloc(sizeof(node)); 

     int len = strlen(buffer); 

     new_node->word = malloc(sizeof(char) * (len)); 

     //avoid \n 
     for(int i = 0; i < len - 1; i++) 
      new_node->word[i] = buffer[i]; 

     new_node->word[len - 1] = '\0'; 

     new_node->next = NULL; 

     int index = hash(buffer); 

     new_node->next = dictionary[index]; 

     dictionary[index] = new_node; 

     size_dict++; 
    } 

    if (ferror(dict)) 
    { 
     fclose(dict); 
     return false; 
    } 

    fclose(dict); 
    return true; 
} 

Yani programı dizeleri ve düğümleri için ince, o zaman serbest ayrılmış tüm belleği işleri ve valgrind (bellek sızıntılarını algılayan bir hata ayıklayıcısını çalıştırdığımda) bellek sızıntısının mümkün olmadığını söylüyor, ancak bir hata olduğunu söylüyor. bir yığın ayırma tarafından yaratılmamış değer oluşturuldu ve beni bu tam satıra yönlendiriyor dictionary için bellek ayırma, yukarıda yazdığım yükleme işlevinin ilk satırı.
Neyi yanlış yapıyorum? Küresel olarak dictionary kullanmamın yanlış olduğunu tahmin ediyorum, bu yüzden herkes bunu küresel olarak tutmanın başka bir yolunu önerebilir ve bu hatayı önleyebilir mi?

+2

Gösterilen kod, hatayı yeniden üretmiyor, bu nedenle büyük olasılıkla bize göstermediğiniz başka bir şeyden kaynaklanıyordur. – Rufflewind

+0

Ama bunu sadece bu satıra gönderdiğim için yaptım, şu kod sadece bir dosya okuyor, kelimeye göre bir sözcük, her bir kelime için bir düğüm oluşturuluyor ve ilgili düğüm listesindeki her düğümün seçimi (bunlardan 26 tanesi) Düğüm nereye gittiyse, bu harfin ilk harfine göre değişir. –

+2

Sorun kodun geri kalanında, neden yayınlamamanın özel bir sebebi? Sana yardım etmeye çalışıyorum ama kodun geri kalanı gerekiyor. –

cevap

7

dictionary = malloc(sizeof(node*) * LISTS); 
if (!dictionary) 
    return false; 

for (size_t i = 0; i < LISTS; ++i) 
    dictionary[i] = NULL; 
+0

NB. Sizin 'new_node-> next = NULL' satırınız, sonra düz yazmanın üzerine giderken gereksizdir. –

+0

evet biliyorum, sözlükte her düğüm için * olmalıydı, aksi halde son düğüm NULL olma özelliğine sahip bir çöp değerine işaret ediyor, teşekkürler. –

3

dictionary'a atadığınız yığın ayırma, döndürülen baytları başlatmayan malloc kullanır. Gönderdiğiniz kodda dictionary Yani başlatılmamış işaretçi bir dizi olmak kadar biter. Muhtemelen bu işaretçilerin bir şekilde bir hata olduğunu bildiği bir şekilde kullanacaksınız.

Bunu düzeltmenin kolay bir yolu, malloc yerine calloc kullanmaktır, çünkü sizin için döndürülen baytları sıfırlar. Veya, baytları kendiniz sıfırlamak için memset kullanın. insanlar zaten tahmin ettiği gibi

dictionary = malloc(sizeof(node*) * LISTS); 

// .... code that does not change dictionary[i] for any i 

new_node->next = dictionary[index]; // use uninitialized pointer 

, bu yalnızca bu döngü girmeden önce NULL olmak tüm işaretçiler önceden ayarlanmış olsaydı çalışacaktır: başlatılmamış bir işaretçi kullanmak güncellenen kodunda

+0

// kodu yazdığım yer ...Yükleme işlevinde, bir dosyadan kelime ile sözcük yüklediğim, her sözcük için yeni bir düğüm oluşturduğum ve dictionary işaret ettiği düğümü, bu düğümlere bir işaretçi ve diğer tüm kod satırlarını atladığım 60 satırlık kodu atladım. node * için bellek ayırdım aslında kullanılan –

+0

Gerçekten benim program düzgün çalışır, düğümleri tarafından rapresents doğru düğümler dizisi * 's dizi dağıtılır ve daha sonra –

+1

serbest kalloc kullanmayan başlatır gerçeği gizler "calloc" işlevini kullanarak "0" olarak başlatılmak istemediğiniz sürece, başka bir sorunu gizliyorsunuz. –

İlgili konular