2015-11-25 4 views
2

Я работаю над функцией destroy для своей программы, но у меня проблемы с ее реализацией, потому что мои структуры смешивают меня. У меня две структуры: 1 для пар <key, value> и другая для массива, размера стола и счетчика. Вот что у меня есть:C - Функция разрушения w/2 структуры

#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; 
} 

но это не работает по многим причинам. Может кто-нибудь объяснить, как я могу освободить все в обеих структурах? Синтаксис меня очень смущает. Нужно ли мне (если я) бесплатный счетчик? Должен ли я делать одну структуру за раз или я должен освобождать узел, когда я нахожусь в каждом индексе в массиве? Спасибо, парни.

+0

Если вы не показываете, где находятся ваши распределения, то все, что мы можем сделать, это угадать, как освободить память. Предположим ли мы, что для каждого узла выделяются как «ключ», так и «значение», или «значение» просто указатель? –

+0

'p' является указателем на' SymTable_T', который сам является typedef для 'struct SymTable *', поэтому вам нужно разыменовать его дважды, и у него нет таких членов, как 'next' или' key'. Вы уверены, что это ваш точный код? – mch

+0

@ DavidC.Rankin Да, предполагается, что ключ и значение уже выделены. –

ответ

0

Трудно точно определить макет памяти, который вы пытаетесь освободить, также не видя, как выделена память. На основании ваших комментариев распределения памяти для массива symTable (элемент инициализируется NULL), ряд указателей на struct Node (Table), которые инициализируются NULL и из которых список узлов выделяются отдельными ассигнования на key и value. Вы держите стартовый адрес к списку узлов в Table.

Предполагая, что symTable является выделенный массив из struct SymTable, и что память выделяется для каждого узла типа struct Node в указатель на указатель на тип Node_t (struct Node) под названием Table для каждого элемента в symTable, и что оба key и value выделяются, вы могли бы попытаться освободив ассоциировать памяти с каждым списком Table в каждом элементе symTable что-то вроде:

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 */ 
} 

Над пуантах r victim указывает на текущий удаляемый узел, позволяющий p удерживать адрес nextp и оставаться в силе после удаления текущего узла. Дайте это пойти и дайте мне знать, если у вас есть проблемы. Если у вас есть какие-либо проблемы, отредактируйте свой вопрос и опубликуйте полный код, показывающий распределение, и я рад работать с вами.

+0

Я добавил свою функцию 'create', которая содержит информацию о распределении памяти. Я попытался реализовать ваш код, но я получаю несколько предупреждений и ошибок. –

+0

ОК, вы указали, где вы выделяете указатели 'S_Table-> Table = (Node_T **) calloc (DEFAULT_TABLE_SIZE, sizeof (Node_T *));' (это должно быть просто 'S_Table-> Table = calloc (DEFAULT_TABLE_SIZE, sizeof (Node_T *));), но вы не указали, где вы выделяете память для каждого узла. Хорошая работа по использованию 'calloc' для обеспечения указателей выделяется' NULL', это предположение, которое я сделал в своем ответе. Можете ли вы опубликовать весь свой код?Я могу, конечно, сделать больше с минимальным полным проверяемым примером, который я могу скомпилировать. См.: [** Как создать MCVE **] (http://stackoverflow.com/help/mcve) –