c - 使用 uthash HASH_ADD_KEYPTR(段错误)

标签 c segmentation-fault uthash

所以我正在尝试将 uthash 与以下结构一起使用

typedef struct hash_item hash_item; 
typedef struct value_List value_List; 

struct hash_item{ 
    void * key; 
    value_List * values;
    UT_hash_handle hh;         /* makes this structure hashable */ 
};

struct value_List{ 
    void * value; 
    value_List * next_val; 
}; 

我的哈希表 HASH_TABLE 是一个全局变量。

hash_item * HASH_TABLE; 

我主要是说

HASH_TABLE = NULL; 

创建我的 hash_item 后,我尝试将它添加到 HASH_TABLE,如下所示。

sem_wait(&table_lock); 
                HASH_FIND_STR( HASH_TABLE, last_token, NEXT_VAL); 
                if( NEXT_VAL ){ /*if already in hashtable, add an occurence*/
                    add_VAL_OCCUR(NEXT_VAL->values, &value);

                    sem_post(&table_lock);
                    continue;
                }
                /* if not in hashtable, add to hashtable*/
                create_hash_item(NEXT_VAL, (void*)last_token, create_value_List((void*)&value));
                HASH_ADD_KEYPTR( hh, HASH_TABLE, NEXT_VAL->key, strlen((char *)NEXT_VAL->key), NEXT_VAL);

                sem_post(&table_lock); 

当我检查我为什么会出现段错误时,gdb 说它在这一行:

HASH_ADD_KEYPTR( hh, HASH_TABLE, NEXT_VAL->key, strlen((char *)NEXT_VAL->key), NEXT_VAL);

我不确定为什么,这是段错误,我似乎无法得到任何进一步的澄清。

有什么想法是什么问题,或者我如何缩小范围以找出问题?

编辑:按要求添加了我的整个代码

#include "uthash.h"
#include <semaphore.h>
#include <stdlib.h> 
#include <pthread.h>
#include <stdio.h>
#include <string.h>

/* Test Commands 
 * 
 * 
 * ./mapred -a wordcount -i threads -m 3 -r 3 q9.sql
*/
#define BUFFER_SIZE 2048 

typedef struct hash_item hash_item; 
typedef struct value_List value_List; 

struct hash_item{ 
    void * key; 
    value_List * values;
    UT_hash_handle hh;         /* makes this structure hashable */ 
};

struct value_List{ 
    void * value; 
    value_List * next_val; 
};

sem_t table_lock;
hash_item * HASH_TABLE;
int debug_start_Map_Threads = 0; 
int debug_main = 1; 
int debug_map = 1, debug_map_wordcount = 1; 
int debug_add_VAL_OCCUR = 1, debug_create_value_List = 1; 
int debug_create_hash_item = 1;



int add_VAL_OCCUR(value_List * CURR_VAL, void * new_VAL){ 
    if( CURR_VAL == NULL || new_VAL == NULL){ 
        if( debug_add_VAL_OCCUR )
        printf("Error in add_VAL_OCCUR\n");
        return -1; 
    }
    value_List * temp = CURR_VAL; 
    CURR_VAL = (value_List*)calloc(1,sizeof(value_List));
    CURR_VAL->value = calloc(1,sizeof(new_VAL)+1); 
    memcpy(CURR_VAL->value, new_VAL, sizeof(new_VAL)); 
    CURR_VAL->next_val = temp; 

    if( debug_add_VAL_OCCUR )
    printf("add_VAL_OCCUR seems to work\n");
    return 0;

}

value_List * create_value_List( void * value){ 
    value_List * new;
    if( value == NULL ){ 
        if( debug_create_value_List )
        printf("Error in create_value_List\n");
        return -1; 
    }

    new = (value_List*)calloc(1,sizeof(value_List)); 
    new->value = calloc(1,sizeof(value)+1); 
    memcpy(new->value, value, sizeof(value)); 
    if( debug_create_value_List )
    printf("create_value_List seems to work %d\n", *(int*)new->value);
    return new;
}

int create_hash_item(hash_item * item, void * key, value_List * values){ 
    if( key == NULL || values == NULL ){ 
        if( debug_create_hash_item )
        printf("Error in create_hash_item %s\n", (char*)key);
        return -1; 
    }
    item = (hash_item*)calloc(1, sizeof(hash_item)); 
    item-> key = calloc(1,sizeof(key)+1); 
    memcpy(item->key, key, sizeof(key)); 
    item->values = values; 

    if( debug_create_hash_item )
    printf("create_hash_item seems to work key = <%s>, value = <%d>\n", (char*)item->key, *(int*)item->values->value);
    return 0;
}

void * map_wordcount(char * fileName){ 
    FILE * F_CHUNK = fopen(fileName, "r"); 
    hash_item * CURR_HASH_TABLE = NULL; 
    hash_item * NEXT_VAL;  
    char buffer[BUFFER_SIZE]; 
    char * last_token; 
    char * delimiter_characters = " \t\n";
    int  value = 1;


    if( F_CHUNK == NULL ){ 
        fprintf( stderr, "Unable to open <%s>", fileName);
    } 

    while( fgets(buffer, BUFFER_SIZE, F_CHUNK) != NULL ){
            last_token = strtok( buffer, delimiter_characters );
            while( last_token != NULL ){
                printf( "<<%s>>\n", last_token );
                sem_wait(&table_lock); 
                HASH_FIND_STR( HASH_TABLE, last_token, NEXT_VAL); 
                if( NEXT_VAL ){ /*if already in hashtable, add an occurence*/
                    add_VAL_OCCUR(NEXT_VAL->values, &value);
                    sleep(1);
                    sem_post(&table_lock);
                    continue;
                }
                /* if not in hashtable, add to hashtable*/
                create_hash_item(NEXT_VAL, (void*)last_token, create_value_List((void*)&value));
                HASH_ADD_KEYPTR( hh, HASH_TABLE, NEXT_VAL->key, strlen((char *)NEXT_VAL->key), NEXT_VAL);
                sleep(1);
                sem_post(&table_lock);
                last_token = strtok( NULL, delimiter_characters );
            }

    }

    return NULL;
}

int start_Map_Threads(int num_threads, const char * fileName, void *(map)(char * fileName)){ 
    int i = 0, file_len = strlen(fileName);
    pthread_t thread[num_threads]; 
    char files[num_threads][file_len+num_threads%10 + 2];

    if( debug_start_Map_Threads )
    printf("num_threads: %d\nlen of arrays: %d, %d", num_threads, sizeof(thread)/sizeof(pthread_t), sizeof(files));
    if( debug_start_Map_Threads )
    printf("fileName recieved = <%s>\n", fileName);

    for(;i< num_threads; i++){
        memset(files[i], '\0', file_len );
        sprintf(files[i], "%s.%d", fileName, i);
        if( debug_start_Map_Threads )
        printf("files[%d] = <%s>\n", i, files[i]); 
    }
    for(i=0; i< num_threads; i++){ 
        if( debug_start_Map_Threads )
        printf("Trying to create <%s>\n", files[i]);
        pthread_create(&thread[i], NULL, map, files[i]);
        if( debug_start_Map_Threads )
        sleep(1);
    }

    for(i = 0; i < num_threads;i++){ 
        if(pthread_join(thread[i], NULL)) {
            fprintf(stderr, "Error joining thread\n");
            return 2;
        }else{ 
            if( debug_start_Map_Threads )
            printf("Thread %d came back\n", i);
        }
    } 
    return 0;

}
int main(int argc, char * argv[]){ 
    int i = 5;
    sem_init(&table_lock, 0,1 );
    char buffer[BUFFER_SIZE]; 
    char *ptr; 
    HASH_TABLE = NULL;
    memset(buffer, '\0', 2000);
    sprintf(buffer,"./split.sh %s %s", argv[9], argv[6] );
    system(buffer);
    if( strcmp( argv[2], "wordcount") == 0 ){ 
        if( debug_main )
        printf("Starting Threads\n");
        start_Map_Threads((int)strtol(argv[6], &ptr ,10), argv[9], map_wordcount);
    }
    return 0;
}

最佳答案

指针语义有问题。在 create_hash_item 函数中,您正在为 item 分配内存,但该地址永远不会在函数外生效,因为您将其分配给局部变量。因此,NEXT_VAL 将保持为 NULL,下次您尝试访问 NEXT_VAL->key 时 - 会发生崩溃。

我不认为哈希表是学习指针的好地方。但无论如何,作为快速解决方案,它应该是这样的:

hash_item *create_hash_item(hash_item * item, void * key, value_List * values){ 
    // ... blah-blah, same code you have
    return item;
}

// ...
NEXT_VAL = create_hash_item(NEXT_VAL, (void*)last_token, create_value_List((void*)&value));

关于c - 使用 uthash HASH_ADD_KEYPTR(段错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22719887/

相关文章:

c++ - Hi-Link HLK-RM04跑openwrt,可以多线程吗?

通过 ctypes 使用 pcap 的 python 段错误

c - UTHash 多级哈希表在 HASH_FIND_STR 上崩溃

c - 了解段错误的堆栈跟踪

c - 错误: misuse of undefined type 'struct IntArray'

c - (int, const char *) 作为 uthash 库的复合键

c - 给定的字符串是否可转换为整数

c - 将静态库的多个不兼容版本链接到一个可执行文件中

python - 我的python客户端向c服务器发送一个整数,但服务器收到0