【问题标题】:C - Destroy function w/ 2 structuresC - 带有 2 个结构的销毁函数
【发布时间】:2016-02-28 21:13:51
【问题描述】:

我正在为我的程序开发一个销毁函数,但我在实现它时遇到了麻烦,因为我的结构混淆了我。我有两种结构:一种用于<key, value> 对,另一种用于数组、表大小和计数器。这是我所拥有的:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "symTable.h"
#define DEFAULT_TABLE_SIZE 61
#define HASH_MULTIPLIER 65599

typedef struct Node
{
    char *key;
    int *value;
    struct Node *next;
} Node_T;

typedef struct SymTable
{
    Node_T **Table;
    int tablesize;
    int counter;
} *SymTable_T;

SymTable_T SymTable_create(void)
{
    SymTable_T S_Table;

    S_Table = malloc(sizeof(SymTable_T *) * DEFAULT_TABLE_SIZE);
    S_Table->Table = (Node_T **) calloc(DEFAULT_TABLE_SIZE, sizeof(Node_T *));

    return S_Table;
}

void symTable_destroy(SymTable_T symTable)
{
    SymTable_T *p, *nextp;
    int i;

    assert(symTable != NULL);

    for (i = 0; i < DEFAULT_TABLE_SIZE; i++)
    {
        for (p = symTable[i]; p != NULL; p = nextp)
        {
            nextp = p->next;
            assert(p->key != NULL);
            free(p->key);
            free(p);
        }
    }
    free(symTable);
    return;
}

但由于许多原因,这不起作用。有人可以解释我如何才能释放这两种结构中的所有东西吗?语法让我很困惑。我需要(应该)免费柜台吗?我应该一次做一个结构,还是应该在数组中的每个索引处释放节点?谢谢大家。

【问题讨论】:

  • 除非您显示分配发生的位置,否则我们所能做的就是猜测如何释放内存。我们是要假设为每个节点分配keyvalue,还是value 只是一个指针?
  • p 是指向SymTable_T 的指针,它本身是struct SymTable * 的typedef,所以你需要解引用它两次并且它没有nextkey 这样的成员.您确定这是您的确切代码吗?
  • @DavidC.Rankin 是的,假设键和值都已分配。
  • SymTable_T 是指针类型非常令人困惑,但 Node_T 不是。我强烈建议不要使用指针类型定义;而是将 Symtable_T 设为结构类型,并在需要指针时写入 SymTable_T *
  • 您可能也应该发布您的创建代码,当我们看不到您分配的内容时,很难说应该释放什么。可以这样回答这个问题:每次拨打malloc(并且地址相同)时,您必须拨打free一次

标签: c struct hashtable free destroy


【解决方案1】:

如果不查看内存是如何分配的,就很难准确地确定您尝试释放的内存布局。根据您的 cmets,您正在为 symTable 的数组分配内存(元素已初始化 NULL),一些指向 struct Node (Table) 的指针已初始化 NULL 并且从中节点列表是为keyvalue 分配了单独的分配。您将 起始地址 保存在 Table 中的节点列表中。

假设symTablestruct SymTable 的已分配数组,并且在指向Node_t 类型的指针(@987654334) 中为struct Node 类型的每个节点分配内存@) 为symTable 中的每个元素命名为Table,并且keyvalue 都已分配,您可以尝试在symTable 的每个元素中释放与每个列表Table 关联的内存,例如:

void symTable_destroy (SymTable_T *symTable)
{
    for (i = 0; i < DEFAULT_TABLE_SIZE && symTable[i]; i++)
    {
        struct Node *p = *(symTable[i]->Table); /* pointer to node  */
        while (p != NULL)               /* for each allocated node  */
        {
            struct Node *victim = p;    /* pointer node to delete   */
            free (victim->key);         /* free key for node        */
            free (victim->value);       /* free value for node      */
            p = p->nextp;               /* set p to next node       */
            free (victim);              /* free node memory         */
        }
        free (symTable[i]->Table);      /* free Table memory        */
    }
    free (symTable);     /* free allocated array of struct SymTable */
}

上面的指针victim指向要删除的当前节点,允许p持有nextp的地址,并在当前节点被删除后保持有效。试一试,如果您有问题,请告诉我。如果您有任何问题,请编辑您的问题并发布显示分配的完整代码,我很乐意与您进一步合作。

【讨论】:

  • 我添加了我的create 函数,它保存了内存分配信息。我尝试实现您的代码,但收到了一些警告和错误。
  • 好的,您已经显示了分配指针 S_Table-&gt;Table = (Node_T **) calloc(DEFAULT_TABLE_SIZE, sizeof(Node_T *)); 的位置(应该是简单的 S_Table-&gt;Table = calloc(DEFAULT_TABLE_SIZE, sizeof(Node_T *)); ),但是您没有显示为每个节点分配内存的位置。很好地使用calloc 来确保分配指针NULL,这是我在回答中做出的假设。你可以发布你的整个代码吗?我当然可以用我可以编译的最小完整可验证示例做更多事情。见:How to create a MCVE
猜你喜欢
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-13
  • 2018-05-02
  • 1970-01-01
  • 2016-11-10
相关资源
最近更新 更多