在我的下面的代码中,我试图创建一个动态可扩展的内存数组。
#include <stdio.h>
#include <stdlib.h>
#define BLOCKSIZE 5
int hash_table_length = 0;
int *currentblock = NULL;
int size_left;
int *hash_table = NULL;
int *start = NULL;
int *create_hash_table() {
int *tmp;
if (currentblock == NULL || size_left == 0) {
if (currentblock == NULL) {
currentblock = (int *) malloc( BLOCKSIZE * sizeof(int));
start = currentblock;
size_left = BLOCKSIZE;
} else {
currentblock = (int *) malloc( BLOCKSIZE * sizeof(int));
size_left = BLOCKSIZE;
}
}
tmp = currentblock++;
size_left -= 1;
return tmp;
}
void build() {
int hash;
int i = 0;
for (i = 0; i < 20; i++) {
hash = i + 3;
if (hash_table_length == 0) {
hash_table = create_hash_table();
hash_table_length++;
} else {
hash_table = create_hash_table();
hash_table_length++;
}
hash_table = &hash;
printf("hash value is %d\n", *hash_table);
}
}
int main() {
build();
// How do I reach the start of the hash table again?
// the below start does not give me the first value
printf("Hash table first value is %d\n", *start);
return 0;
}
我的问题是希望遍历hash_table中存储的值。我无法访问hash_table的第一个元素/地址。我希望打印出哈希表中存储的所有值。怎么办呢?
答案 0 :(得分:1)
在您的代码中,hash
值永远不会存储在哈希表中(currentblock
内)。在create_hash_table()
函数内部,您为新块分配内存,但从不在此块中存储值。因此,如果您尝试取消引用这些int*
位置中的任何一个,则可能会获得垃圾值(可能为0)。
当您取消引用start
指针时,这正是main()函数内部正在发生的事情。它实际上指向哈希表的开始,并且由于该位置未初始化,因此它给出了0的输出。
要在哈希表中实际存储值,请在build()
:
hash_table = &hash;
为:
*hash_table = hash; // Store value of 'hash' inside the memory location pointed to by hash table(which happens to be 'current_block' inside build())
现在,如果您尝试运行代码,它将输出3。
关于如何遍历整个哈希表的问题的第二部分:使用此代码无法完成。这是因为malloc的整数块之间没有联系。 malloc()调用可以从堆中分配任何可用内存块。因此,在当前形式中,您已经断开了无法遍历的位置块。
您可以使用realloc来增加当前块的大小,而不是malloc。 realloc为较大的块分配内存,并将以前的数据复制到此新块。这基本上允许您使用start
遍历整个哈希表。
您可以这样做:
#include <stdio.h>
#include <stdlib.h>
#define BLOCKSIZE 5
int hash_table_length = 0;
int *currentblock = NULL;
int size_left;
int *hash_table = NULL;
int *start = NULL;
int *create_hash_table() {
int *tmp;
if (currentblock == NULL || size_left == 0) {
if (currentblock == NULL) {
currentblock = (int *) malloc(BLOCKSIZE * sizeof(int));
start = currentblock;
size_left = BLOCKSIZE;
} else {
/* Call realloc() to allocate new memory block of size (hash_table_length+BLOCKSIZE) and copy previous data*/
currentblock = ((int *) realloc(start,(hash_table_length + BLOCKSIZE) * sizeof(int))) + hash_table_length;
size_left = BLOCKSIZE;
}
}
tmp = currentblock++;
size_left -= 1;
return tmp;
}
void build() {
int hash;
int i = 0;
for (i = 0; i < 20; i++) {
hash = i + 3;
if (hash_table_length == 0) {
hash_table = create_hash_table();
hash_table_length++;
} else {
hash_table = create_hash_table();
hash_table_length++;
}
/* Store value of hash inside the hash_table */
*hash_table = hash;
printf("hash value is %d\n", *hash_table);
}
}
int main() {
int i;
build();
printf("Hash table first value is %d\n", *start);
/* Traverse the hash table */
for(i = 0; i < hash_table_length; ++i)
printf("hash_table[%d] = %d\n",i,*start++);
return 0;
}