以下代码用于创建和管理哈希表: 哈希.c:
#include <stdio.h>
#include <stdlib.h>
#include "hash.h"
typedef struct node {
record_t rec;
struct node *next;
} node_t;
node_t *hashArray [MAX_SIZE];
void initHashTable() {
for(int i = 0; i < MAX_SIZE; i++) {
hashArray[i] = NULL;
}
}
int myHashFunc(long long phone_num)
{
return phone_num % MAX_SIZE;
}
int searchRecord(long long phone, record_t *record)
{
int hix;
node_t *ptmp;
hix = myHashFunc(phone);
ptmp = hashArray[hix];
if(ptmp->rec.phone == phone){
*record = (ptmp->rec);
return SUCCESS;
}
while(ptmp){
if(ptmp->rec.phone == phone){
*record = ptmp->rec;
return SUCCESS;
}
ptmp = ptmp->next;
}
return NOT_FOUND_ERR;
}
int addRec(record_t *rec)
{
int hix;
node_t *pn = (node_t *)malloc(sizeof(node_t));
if(pn == NULL) return NO_MEMORY_ERR;
pn->rec = *rec;
hix = myHashFunc(rec->phone);
pn->next = hashArray[hix];
hashArray[hix] = pn;
return SUCCESS;
}
int delRec(long long phone)
{
int hix;
node_t *ptmp, *delnode;
hix = myHashFunc(phone);
ptmp = hashArray[hix];
if(ptmp == NULL || ptmp == 0){
return NOT_FOUND_ERR;
}
if(ptmp->rec.phone == phone){
delnode = ptmp;
hashArray[hix] = ptmp->next;
free(delnode);
return SUCCESS;
}
while(ptmp->next){
if(ptmp->next->rec.phone == phone){
delnode = ptmp->next;
ptmp->next = ptmp->next->next;
free(delnode);
return SUCCESS;
}
ptmp = ptmp->next;
}
return NOT_FOUND_ERR;
}
void displayAllRecords()
{
int i;
node_t *ptmp;
printf("Name Phone Number\n");
printf("-------------------- ----------\n");
for(i = 0; i < MAX_SIZE; i++){
ptmp = hashArray[i];
while(ptmp){
printf("%19s %10lld\n",ptmp->rec.name, ptmp->rec.phone);
ptmp = ptmp->next;
}
}
}
int destroyhash()
{
int i;
node_t *temp, *curr;
for(i = 0; i < MAX_SIZE; i++){
curr = hashArray[i];
while(curr != NULL){
temp = curr;
curr = curr->next;
free(temp);
}
}
}
test.c: #include <stdio.h>
#include "hash.h"
enum{SER = 1, ADD, DEL, DISP, XIT};
int main()
{
struct record rec;
int option, state;
void initHashTable();
while(1)
{
printf("Enter 1:To search and get, 2: Add a record, 3: Delete a record\n");
printf("Enter your option: ");
scanf("%d", &option);
long long phone;
switch(option)
{
case SER:
printf("Enter the phone number to search\n");
scanf("%lld",&phone);
state = searchRecord(phone, &rec);
if(state == SUCCESS)
printf("Name: %s, phone: %lld\n", rec.name, rec.phone);
else
printf("Search failed with error %d\n", state);
break;
case ADD:
printf("Enter phone number: \n");
scanf("%lld",&rec.phone);
getc(stdin);
printf("Enter name\n");
scanf("%[^\n]",rec.name);
state = addRec(&rec);
if(state == SUCCESS)
printf("Record added successfully\n");
else
printf("Record addition failed with error %d\n", state);
break;
case DEL:
printf("Enter phone number to search\n");
scanf("%lld",&phone);
state = delRec(phone);
if(state == SUCCESS)
printf("Record deleted successfully\n");
else
printf("Record deletion failed with error %d\n", state);
break;
case DISP:
displayAllRecords();
break;
case XIT:
return 0;
break;
}
}
int destroyhash();
}
这是 valgrind 的输出:
==68577== Memcheck, a memory error detector
==68577== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==68577== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==68577== Command: ./myprog arg1 arg2
==68577== Parent PID: 37429
==68577==
==68577==
==68577== HEAP SUMMARY:
==68577== in use at exit: 160 bytes in 4 blocks
==68577== total heap usage: 7 allocs, 3 frees, 2,248 bytes allocated
==68577==
==68577== 160 bytes in 4 blocks are still reachable in loss record 1 of 1
==68577== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==68577== by 0x1095C6: addRec (in /home/biggmacbilly/adv_C/hash/myprog)
==68577== by 0x10938E: main (in /home/biggmacbilly/adv_C/hash/myprog)
==68577==
==68577== LEAK SUMMARY:
==68577== definitely lost: 0 bytes in 0 blocks
==68577== indirectly lost: 0 bytes in 0 blocks
==68577== possibly lost: 0 bytes in 0 blocks
==68577== still reachable: 160 bytes in 4 blocks
==68577== suppressed: 0 bytes in 0 blocks
==68577==
==68577== For lists of detected and suppressed errors, rerun with: -s
==68577== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
valgrind 输出显示我在 addrec 和 main 函数中存在内存泄漏。这是我第一次使用 valgrind,我无法找出给定程序中的内存泄漏。我该如何修复这些内存泄漏?预先感谢您。
valgrind 命令: valgrind --leak-check=full --show-leak-kinds=all --log-file="output.txt" ./myprog 使用的编译器:GCC
像往常一样,在 C 语言中重新发明方轮是一个问题。
使用 C++ 和
std::unordered_map
。您将需要四分之一的代码,而 C++ 的 RAII 将使您的代码更难泄漏。类似的论点也适用于 Rust,尽管这是一个更大的进步。
正如评论中所说,你没有打电话给
destroyhash()
。
此外,除了为 XIT 点击“5”之外,我没有看到任何摆脱“while (1)”循环的方法。从 main 返回。据我所知,你放置“destroyhash()”的地方是无法访问的。
以下应该完成这项工作:
case XIT:
destroyhash();
return 0;