因此,我正在创建一个密码保管库,并且需要能够将哈希表保存到二进制文件,并在登录时将二进制文件中的相同内容读回到程序哈希表中
我已经用 fwrite 和 fread 玩了整整 4 个小时,但似乎找不到我哪里出错了。目前我正在发生段错误,我已尝试使用 GDB 来找到它,但只是收到消息:
Thread 2 received signal SIGSEGV, Segmentation fault.
0x00007fff9a9a16a0 in ?? ()
我读取文件的代码是:
void readFile(char * fileName, HTable * hashTable){
//Create file pointer and point it at fild to open
FILE * fp;
fp = fopen(fileName, "rb+");
//check if file exists
if(!fp){
printf("File could not be opened\n");
return;
}
//Set a temp Node to hold data, read data into the temp Node
//and insert temp into hashtable
Node * temp;
while(1){
fread(&temp, sizeof(Node), 1, fp);
insertData(hashTable, temp->key, temp->data);
if(feof(fp) != 0)
break;
printf("is this working?\n");
}
//Close file pointer
fclose(fp);
}
我写入文件的代码是:
void saveFile(char * fileName, HTable * hashTable){
//Create a FILE pointer and point it to the file to open or create
FILE * fp;
fp = fopen(fileName, "wb+");
//If the file does not exist or cannot be created give error message
if(!fp){
printf("ERROR: File could not be created\n");
return;
}
//for each index of the hashTable write its contents to the file
for(int i = 0; i < hashTable->size; i++){
Node * temp = hashTable->table[i];
while(temp != NULL){
fwrite(&temp, sizeof(Node), 1, fp);
temp = temp->next;
printf("saved....\n");
}
printf("Index %d saved\n", i);
}
//Close file pointer
fclose(fp);
}
我知道段错误不是来自 insertData 函数,因为我已经测试过它并且知道它可以正常工作。我对我做错的事情的最佳猜测是我的 fwrite 条件不正确,或者当我读取数据时我在某处错误地管理内存。
HashTable 结构也是:
typedef struct HTable
{
size_t size;
Node **table;
void (*destroyData)(void *data);
int (*hashFunction)(size_t tableSize, char * key);
void (*printData)(void *toBePrinted);
}HTable;
我的节点是:
typedef struct Node
{
char * key;
void *data;
struct Node *next;
} Node;
感谢您的反馈!!
最佳答案
首先,fwrite()/fread()的参数1是void *,而不是**void ****。
第二,你不能使用fwrite()/fread()来保存/恢复你的数据,因为Node的成员{key, data}是指针,指示额外的数据内存数据,但是使用 fwrite()/fread() 只是操作指针 {char *, void *, Node *},而不是额外的数据。
对于 key ,有一个示例:
Node n;
n.key = malloc(sizeof(char) * DEF_SIZE); // Suppose n.key = 0xb8b270
strcpy(n.key, "Hello world!");
fwrite(&n, sizeof(Node), 1, fp); // Only 0xb8b270 is written.
仅将字符串(n.key)的地址写入文件,而不将字符串“Hello world”写入文件。你能明白我说的吗?
简而言之,fwrite()/fread() 只是写入/读取原始数据,当您的结构体包含指示额外内存数据的指针时,请小心使用它们。
对于结构
typedef struct Item
{
char key[128];
char value[128];
struct Item *next;
} Item;
这里使用fwrite()/fread()可能没问题,因为{char[], char[], Item *}会被写入/读取,只有{Item *}是无效数据,{char[], char []}可以正确保存/恢复。
我想在您的情况下使用 fprintf()/fscanf() 来替换 fwrite()/fread() 。
第三,我的一个 HashMap 实现可能可以帮助你: https://github.com/foreverpersist/hashmap
关于c - C语言将二进制文件读入HashTable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50960037/