C - 检查struct数组的索引是否未初始化

时间:2016-07-17 03:44:28

标签: c pointers

我在C中制作HashMap但是在检测节点何时初始化时遇到问题。

摘自我的代码:

static struct Node
{
    void *key, *value;
    struct Node *next;
};


struct Node **table;
int capacity = 4;
table = malloc(capacity * sizeof(struct Node));

// At this point I should have a pointer to an empty Node array of size 4.

if (table[0] != NULL)
{
    // This passes
}

我不知道我能在这做什么。我已经阅读了大量这种性质的其他帖子,他们的解决方案对我来说都没有任何意义。

enter image description here

2 个答案:

答案 0 :(得分:1)

malloc未初始化已分配的内存。您可以使用calloc对内存进行零初始化。

// Not sizeof(struct Node)
// table = calloc(capacity, sizeof(struct Node));
table = calloc(capacity, sizeof(*table));

之后,使用:

是有意义的
if (table[0] != NULL)
{
   ...
}

答案 1 :(得分:-1)

我建议您考虑使用一组函数创建的HashMapCollection类型,以处理您需要的各种内存操作。

所以你可能有类似下面的代码。我没有测试过这个,甚至没有编译它,但它是一个起点。

下面的FreeHashMapCollection()函数将处理HashMapCollection以释放其中包含的内容,然后释放管理数据结构。这可能不是你想要做的,所以你可以考虑这个。

以下的想法是为HashMapCollection结构提供单个指针,并且HashMapNode结构的数组或列表紧跟管理数据,因此单个free()将释放一切都在。

typedef struct _TAGHashMapNode {
    void *key, *value;
    struct _TAGHashMapNode  *next;
} HashMapNode;

typedef struct {
    int  iCapacity;   // max number of items
    int  iSize;       // current number of items
    HashMapNode *table;  // pointer to the HashMapNode table
} HashMapCollection;

然后有一个函数来分配正确初始化的特定容量的HashMapCollection

HashMapCollection *AllocateHashMapCollection (int iCapacity)
{
    HashMapCollection *p = malloc (sizeof(HashMapCollection) + iCapacity * sizeof(HashMapNode));

    if (p) {
        p->table = (HashMapNode *)(p + 1);
        p->iCapacity = iCapacity;
        p->iSize = 0;
        memset (p->table, 0, sizeof(HashMapNode) * iCapacity);
    }
    return p;
}

HashMapCollection *ReallocHashMapCollection (HashMapCollection *p, int iNewCapacity)
{
    HashMapCollection *pNew = realloc (p, sizeof(HashMapCollection) + sizeof(HashMapNode) * iNewCapacity);

    if (pNew) {
        pNew->table = (HashMapNode *)(pNew + 1);
        if (p == NULL) {
          // if p is not NULL then pNew will have a copy of that.
          // if p is NULL then this is basically a malloc() so initialize pNew data.
          pNew->iCapacity = pNew->iSize = 0;
        }
        if (iNewCapacity > pNew->iCapacity) {
            // added more memory so need to zero out that memory.
            memset (pNew->table + iCapacity, 0, sizeof(HashMapNode) * (iNewCapacity - pNew->iCapacity));
        }
        pNew->iCapacity = iNewCapacity;    // set our new current capacity
        p = pNew;   // lets return our new memory allocated.
    }
    return p;    // return either old pointer if realloc() failed or new pointer
}

void FreeHashMapCollection (HashMapCollection *p)
{
    // go through the list of HashMapNode items and free up each pair then
    // free up the HashMapCollection itself.

    for (iIndex = 0; iIndex < p->iCapacity; iIndex++) {
        if (p->table[iIndex].key) free (p->table[iIndex].key);
        if (p->table[iIndex].value) free (p->table[iIndex].value);
        // WARNING ***
        // if these next pointers are actually pointers inside the array of HashMapNode items
        // then you would not do this free as it is unnecessary.
        // this free is only necessary if next points to some memory area
        // other than the HashMapNode table of HashMapCollection.
        if (p->table[iIndex].next) free (p->table[iIndex].next);
        // even though we are going to free this, init to NULL
        p->table[iIndex].key = NULL;
        p->table[iIndex].value = NULL;
        p->table[iIndex].next = NULL;
    }
    free (p);    // free up the memory of the HashMapCollection
}