提问人:M K 提问时间:10/30/2023 更新时间:10/31/2023 访问量:82
为什么访问我的哈希表的单元格会返回问号?
Why does accessing the cells of my hashtable return question marks?
问:
我想用从用户输入文件中读取的字符填充一个哈希表,作为字符数组(即第一个元素是字符,第二个元素是 NULL 字符的字符数组——比如“a”或“b”......你明白了)。
为此,我创建了一个哈希表结构以及基本操作(见下文)
// hashtable structure
struct hashTable{
linkedList* cells;
int capacity;
};
typedef struct hashTable hashTable;
// hashtable function prototypes
int hashFunction(char* s, int capacity);
hashTable creation_hashTable(int capacity);
bool presence_test_hashTable(hashTable h, char* s);
void insertion_hashTable(hashTable h, char* s);
void increment_hashTable(hashTable h, char* s);
基于链表结构(见下文)。
// linked list node
struct node{
char* symbol;
int weight;
struct node* succ;
};
typedef struct node node;
// linked list structure
struct linkedList{
node* head;
};
typedef struct linkedList linkedList;
// linked list function prototypes
linkedList creation_linkedList();
bool search_linkedList(linkedList l, char* s);
void insertion_linkedList(linkedList *l, node n);
与 hashTable 和 linkedList 结构关联的所有函数似乎都可以正常工作。这是我创建的用于填充哈希表的函数:
hashTable readFile(char* fileName){
FILE* p = fopen(fileName, "r");
assert(p);
hashTable* h = malloc(sizeof(hashTable));
*h = creation_hashTable(fileLength(fileName));
char* current = malloc(2);
current[1] = 0;
while (!feof(p)){
current[0] = fgetc(p);
if (!presence_test_hashTable(*h,current))
insertion_hashTable(*h,current);
increment_hashTable(*h,current);
}
fclose(p);
return *h;
}
该函数似乎工作正常:当我打印出非 NULL 单元格的权重值时,我会得到相应的权重。
但是,在终端中编译并运行以下内容:
int main(){
hashTable h = readFile("li_def.txt"); // lorem ipsum filler text file
for (int i = 0; i < h.capacity; ++i){
if (h.cells[i].head){
printf("%s\n", h.cells[i].head->symbol);
}
}
exit(0);
}
返回问号行,如
?
?
...
坦率地说,我根本不确定这里发生了什么。如上所述,我能够毫无问题地访问单元格的权重值,因此在基本层面上,该函数正在执行应有的操作。
我不确定如何处理这个问题,因为我无法访问非 NULL 单元格的符号值。问题出在哪里?是否正在填充符号值?如果是这样,为什么它们被打印出来作为问号?
任何帮助将不胜感激。提前致谢。
答:
“symbol” 是一个 char*(指针),它指向长度为 2(1 个字符 + null 个字符)的字符数组。您得到“?”作为输出,因为您使用的是“%s”,但“%s”需要以 null 结尾的字符串,因此内容未正确格式化为字符串。此外,函数中的变量是指向长度为 2 的字符数组的指针,并在循环的每次迭代中被覆盖。这基本上意味着你将一堆指针存储在同一个内存位置,所以当你打印它们时,“%s”找不到一个空字符,它只会给你一个问号。这意味着您需要为每个“符号”单独分配内存。另外,请记住,当您不再使用该函数时,请使用该函数清除已分配的内存。printf("%s\n", h.cells[i].head->symbol);
current
readFile()
free();
hashTable readFile(char* fileName) {
FILE* p = fopen(fileName, "r");
assert(p);
hashTable* h = malloc(sizeof(hashTable));
*h = creation_hashTable(fileLength(fileName));
char* current = malloc(2);
current[1] = '\0';
while (!feof(p)) {
current[0] = fgetc(p);
if (!presence_test_hashTable(*h, current)) {
char* new_symbol = malloc(2);
new_symbol[0] = current[0];
new_symbol[1] = '\0';
insertion_hashTable(*h, new_symbol);
}
increment_hashTable(*h, current);
}
free(current);
fclose(p);
return *h;
}
评论
insertion_hashTable
strdup
char*
void insertion_hashTable(hashTable h, char* s);
hashTable
while (!feof(p)){
总是错的。hashTable* h = malloc(...); *h = ...; ,.,,; return *h;
创建内存泄漏。没有内存泄漏的相同结果可以通过以下方式实现:但这不一定正确。你最想要的是总是传递指向 的指针,永远不要重视它自己。hashTable h = creation_hashTable(...); ...; return h;
hashTable
hashTable