在C中创建一个可动态扩展的内存阵列



在下面的代码中,我试图创建一个可动态扩展的内存数组。

#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 %dn", *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 %dn", *start);
return 0;
}

这里的问题是,我希望遍历存储在hash_table中的值。我无法访问hash_table的第一个元素/地址。我希望打印出存储在哈希表中的所有值。如何做到这一点?

在代码中,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 %dn", *hash_table);
}
}
int main() {
int i;
build();
printf("Hash table first value is %dn", *start);
/* Traverse the hash table */
for(i = 0; i < hash_table_length; ++i)
printf("hash_table[%d] = %dn",i,*start++);
return 0;
}

最新更新