如何动态地将新数据添加到2D阵列?

时间:2017-03-13 21:29:43

标签: c pointers multidimensional-array hashtable dynamic-memory-allocation

我想使用链接冲突处理来实现一个简单的哈希表。 的 main.c中:

int main ()
{
    const int size = 20;
    const int key = 30;
    const int data = 40;

    htable ht;
    htable_init(&ht, size);
    htable_insert(&ht, key, data);
    htable_insert(&ht, key+1, 22);
    htable_insert(&ht, key+2, 23);
    htable_insert(&ht, key+2, 23);
    assert(htable_get(&ht, key) == data); // Expected: 40
    int d = htable_get(&ht, 415);
    assert(htable_delete(&ht, key) == data); // Expected: 40
    assert(htable_delete(&ht, key) == 0); // Expected: 0
    htable_destroy(&ht);

    // It is recommended to do further tests on your own

    return 0;
}

htable.h:

struct _ht_entry_ {
    int key;
    int data;
    struct _ht_entry_* next;
    struct _ht_entry_* prev;
};
typedef struct _ht_entry_ ht_entry;

struct _htable_ {
    ht_entry** entries;
    int size;
};

htable.c:

void htable_init(htable* ht, int initial_size)
{
    ht->entries = (ht_entry**) calloc(initial_size, sizeof(ht_entry*));
    if(ht->entries)
    {
        ht->size = initial_size;
    }
}

void htable_insert(htable* ht, int key, int data)
{
    ht_entry* newEntry = malloc(sizeof(ht_entry));
    if(!newEntry)
        return;

    newEntry->data = data;
    newEntry->key = key;
    newEntry->next = NULL;
    newEntry->prev = NULL;

    ht_entry** entries = ht->entries;
    *entries = newEntry;
    newEntry->data = 1;
    *(entries + 1) = newEntry;
    newEntry->data = 2;
    *(entries + 2) = newEntry;
    newEntry->data = 3;
    *(entries + 3) = newEntry;
    newEntry->data = 4;
    int i = 0;
    for ( i = 0; i < 3; i++ ) {
        ht_entry* entry = *(entries + i);
        printf("*(entries + %d) : %p\n",  i, *(entries + i) );
    }
}  

在上面的示例中,我尝试了几种方法将新条目存储在HashTable中,但没有一种方法可行。 我也不明白为什么地址是相同的。

输出:

*(entries + 0) : data: 2  0x60003a410
*(entries + 1) : data: 2  0x60003a410
*(entries + 2) : data: 2  0x60003a410

我还尝试了entries[0][0] = newEntry;,因为我认为ht_entry** entries;2D Array,但也不起作用。

那么如何填写我的HashTable

1 个答案:

答案 0 :(得分:1)

我们来看看htable_insert。首先,在堆上创建一个新条目并保留指向它的指针(名为newEntry)。然后设置keydata

到目前为止一切顺利。

现在您取消引用entries并将其值设置为newEntry。由于entries是一个指向指针的数组(2D只是一个奇特的名称),因此取消引用它会为您提供指向ht_entry的指针。这意味着你不将结构newEntry点复制到数组中,而只是保存它的指针。然后再继续这样做3次,每次都在下一个更大的索引处。最后,条目填充了指向同一结构的4个指针。因此,当您打印它的地址时,您将始终获得相同的地址。