2014-09-16 5 views
-4
  1. Я пытаюсь реализовать идеальную хеш-функцию для заданного набора 0,1 миллион уникальных ключей. В процессе разработки кода iam получает ошибку сегментации. Проблема может быть в функции insert_hash. Но будучи новичком в C, я не могу понять его. Вот полный код.valgrind-invalid операции чтения и записи

    # include<stdio.h> 
    # include <stdlib.h> 
    # define array_size 1000000 
    /* Function to calculate x raised to the power y */ 
    int keys[1000000]; 
    unsigned long long p = 100000000019; 
    int power(int x, unsigned int y) { 
    if (y == 0) 
        return 1; 
    else if (y % 2 == 0) 
        return power(x, y/2) * power(x, y/2); 
    else 
        return x * power(x, y/2) * power(x, y/2); 
    } 
    int rand_number() { 
    //generate 9 digit random numbers with in range a and b; 
    int a = 100000000, b = 999999999, num; 
    num = rand() % (b - a + 1) + a; 
    return num; 
        } 
    
    struct hash { 
    int count, a, b, m; 
    int *dyn_array; 
    }*ptr[array_size], *tmp = NULL; 
    void insert_hashkey(int hash1, int key) { 
    int arraysize = 1, i, hash_value; 
    static int primaryhashcount = 0, secondhashcount = 0; 
    
        if (ptr[hash1]->count == 1) { 
        primaryhashcount++; 
        //ptr[hash1]=NULL; 
        ptr[hash1]->dyn_array = (int*) malloc((sizeof(int)) * arraysize); 
        if (ptr[hash1]->dyn_array == NULL) { 
         printf("out of memory\n"); 
         exit(1); 
        } 
        ptr[hash1]->dyn_array[0] = key; 
        printf("\n ptr[%d]->dyn_array[0]=%d %d", hash1, key, primaryhashcount); 
        } else { 
        printf("\n entered in to else part"); 
        //ptr[hash1]=a; 
        secondhashcount++; 
    
        tmp = (struct hash*) malloc(sizeof(struct hash)); 
        tmp->m = (ptr[hash1]->count) * (ptr[hash1]->count); 
        tmp->count = (ptr[hash1]->count); 
        --(ptr[hash1]->count); 
        arraysize = (ptr[hash1]->count) * (ptr[hash1]->count); 
        //tmp=a; 
        tmp->dyn_array = (int*) malloc((sizeof(int)) * arraysize); 
        if (tmp->dyn_array == NULL) { 
         printf("out of memory\n"); 
         exit(1); 
        } 
        tmp->a = rand_number(); 
        tmp->b = rand_number(); 
        for (i = 0; i < tmp->m; i++) 
         tmp->dyn_array[i] = -1; 
        for (i = 0; i < arraysize; i++) { 
         if (ptr[hash1]->dyn_array[i] != -1) { 
          hash_value = (((tmp->a) * (ptr[hash1]->dyn_array[i]) + tmp->b) 
            % p) % (tmp->m); 
          printf("\n first if success"); 
          if (tmp->dyn_array[hash_value] == -1) { 
           tmp->dyn_array[hash_value] = ptr[hash1]->dyn_array[i]; 
             secondhashcount, tmp->count, hash1, hash_value, 
             (ptr[hash1]->dyn_array[i]), tmp->m); 
          } 
         } 
    
        } 
        hash_value = (((tmp->a) * key + tmp->b) % p) % (tmp->m); 
        if (tmp->dyn_array[hash_value] == -1) { 
         tmp->dyn_array[hash_value] = key; 
         printf(
           "\n second hash count=%d count=%d ptr[%d]->dyn_array[%d]=%d,m=%d", 
           secondhashcount, tmp->count, hash1, hash_value, key, 
           tmp->m); 
        } else 
         printf("\n collision"); 
        free(ptr[hash1]->dyn_array); 
        free(ptr[hash1]); 
        ptr[hash1] = tmp; 
        tmp = NULL; 
    
        } 
        } 
    
    int hash_fun(int key, int a, int b, unsigned long long p) { 
    int hash_val; 
    hash_val = (((a * key) + b) % p) % 1000000; 
    return hash_val; 
        } 
    void main() { 
    int i = 0, hash1, count = 0, j; 
    char ch; 
    int a, b, m; 
    time_t t; 
    FILE *fp; 
    fp = fopen("input.in", "r"); 
    /* Intializes rand_num number generator */ 
    srand((unsigned) time(&t)); 
    
    for (i = 0; i < array_size; i++) { 
    
        ptr[i] = NULL; 
    } 
    a = 774877719; 
    b = 271009528; 
    i = 0; 
    while (fscanf(fp, "%d", &keys[i++]) == 1) 
        ; 
    printf("\n read keys successfully from file"); 
    //finding the hash values of array 
    for (i = 0; i < 100000; i++) { 
        hash1 = hash_fun(keys[i], a, b, p); 
        if (ptr[hash1] == NULL) { 
         // create a structure of ni2 elements for each pointer where ni is the   number of collisions 
         // printf("\nmaximum size=%d",malloc(MAX)); 
    
         ptr[hash1] = (struct hash *) malloc(sizeof(struct hash)); 
         if (ptr[hash1] == NULL) { 
          printf("out of memory\n"); 
          exit(1); 
         } 
         ptr[hash1]->count = 1; 
         insert_hashkey(hash1, keys[i]); 
    
        } else { 
         ++(ptr[hash1]->count); 
         insert_hashkey(hash1, keys[i]); 
        } 
    } 
    for (i = 0; i < array_size; i++) { 
        if (ptr[hash1] != NULL) 
         free(ptr[hash1]); 
    } 
    } 
    

2.the Ниже приводится отчет Valgrind. но IAM не в состоянии найти точную проблему в моем коде, как все кажется правильным для меня после того, как пытаться исправить за 6 hours.please помочь мне в этом контексте

==3595== LEAK SUMMARY: 
    ==3595== definitely lost: 4 bytes in 1 blocks 
    ==3595== indirectly lost: 0 bytes in 0 blocks 
    ==3595==  possibly lost: 0 bytes in 0 blocks 
    ==3595== still reachable: 2,287,100 bytes in 190,411 blocks 
==3595==   suppressed: 0 bytes in 0 blocks 
==3595== Reachable blocks (those to which a pointer was found) are not shown. 
==3595== To see them, rerun with: --leak-check=full --show-leak-kinds=all 
==3595== 
==3595== ERROR SUMMARY: 1026216 errors from 11 contexts (suppressed: 0 from 0) 
==3595== 
==3595== 62 errors in context 1 of 11: 
==3595== Invalid write of size 4 
==3595== at 0x8048A46: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== Address 0x449be94 is 4 bytes after a block of size 16 alloc'd 
==3595== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048807: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== 
==3595== 
==3595== 110 errors in context 2 of 11: 
==3595== Invalid read of size 4 
==3595== at 0x8048976: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== Address 0x439a804 is 0 bytes after a block of size 4 alloc'd 
==3595== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048807: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== 
==3595== 
==3595== 110 errors in context 3 of 11: 
==3595== Invalid read of size 4 
==3595== at 0x8048955: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== Address 0x439a804 is 0 bytes after a block of size 4 alloc'd 
==3595== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048807: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== 
==3595== 
==3595== 113 errors in context 4 of 11: 
==3595== Invalid read of size 4 
==3595== at 0x80488C4: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== Address 0x439a804 is 0 bytes after a block of size 4 alloc'd 
==3595== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048807: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== 
==3595== 
==3595== 457 errors in context 5 of 11: 
==3595== Invalid read of size 4 
==3595== at 0x804889C: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== Address 0x4487004 is 0 bytes after a block of size 4 alloc'd 
==3595== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048807: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== 
==3595== 
==3595== 3552 errors in context 6 of 11: 
==3595== Invalid read of size 4 
==3595== at 0x8048A2C: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== Address 0x425110c is 8 bytes after a block of size 4 alloc'd 
==3595== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048807: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== 
==3595== 
==3595== 3561 errors in context 7 of 11: 
==3595== Invalid write of size 4 
==3595== at 0x8048957: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== Address 0x425110c is 8 bytes after a block of size 4 alloc'd 
==3595== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048807: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== 
==3595== 
==3595== 3561 errors in context 8 of 11: 
==3595== Invalid read of size 4 
==3595== at 0x8048929: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== Address 0x425110c is 8 bytes after a block of size 4 alloc'd 
==3595== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048807: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== 
==3595== 
==3595== 14690 errors in context 9 of 11: 
==3595== Invalid write of size 4 
==3595== at 0x8048864: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== Address 0x4228b84 is 0 bytes after a block of size 4 alloc'd 
==3595== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048807: insert_hashkey (in /home/abhimint/Desktop/hashing/a.out) 
==3595== by 0x8048CEA: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== 
==3595== 
==3595== 999999 errors in context 10 of 11: 
==3595== Invalid free()/delete/delete[]/realloc() 
==3595== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048D29: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== Address 0x4e3b6b0 is 0 bytes inside a block of size 20 free'd 
==3595== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3595== by 0x8048D29: main (in /home/abhimint/Desktop/hashing/a.out) 
==3595== 
==3595== ERROR SUMMARY: 1026216 errors from 11 contexts (suppressed: 0 from 0) 

ответ

0

Попробуйте использовать в Valgrind: --trace-origins=yes Для каждого недопустимого чтения/напишите, это даст вам имя функции, где это произойдет.

Недопустимое чтение означает, что вы, вероятно, пытаетесь прочитать переменную, которая не была инициализирована или была удалена.

+0

Я попробовал и обнаружил, что проблема заключается в функции insert_hash. Но iam не может найти точную проблему. –

+0

Кажется, вы предполагаете, что ptr [hash1] не имеет значения null или nullptr в функции insert_hashkey. Может быть, попробуйте проверить, является ли NULL или nullptr – wjk2a1

+0

да, он возвращает null.but, есть ли ситуация, когда malloc не может выделить память.if так, как исправить его –

Смежные вопросы