C Ошибка сегментации при добавлении хеш-узла - PullRequest
0 голосов
/ 05 февраля 2011

У меня есть структура типа:

struct hashnode_s {
    struct hashnode_s *next;
    char *key;
    ValueType tag;
    union
    {
        int IntegerValue;
        char *StringValue;
    } u;
    int IsInCycle;
};

И когда я добавляю элемент типа String, я могу, код для него -

int hashtbl_InsertString(HASHTBL *hashtbl, const char *key, const char *value)
{
    struct hashnode_s *node;
    hash_size hash;

    hash = SearchForHashIndex(hashtbl, key,value);

    if(hash == -1)
    {
        hash=hashtbl->hashfunc(key);
    }
    /* adding the first node  if not applicable (this is based on value string)*/

    if(hashtbl->nodes[hash]== NULL)
    {
        node = malloc(sizeof(struct hashnode_s));
        node->key = key;
        node->tag = StringConst;
        node->u.StringValue = value;
        node->next = NULL;
        hashtbl->nodes[hash] = node;
    }
    else
    {
        node = hashtbl->nodes[hash];

        if(node->next ==NULL)
        {
            struct hashnode_s *nextNode;
            nextNode = malloc(sizeof(struct hashnode_s));

            if(strcmp(node->u.StringValue,key)==0)
            {
                /* set next */
                nextNode->key = key;
                nextNode->tag = StringConst;
                nextNode->u.StringValue = value;
                nextNode->next = NULL;
                node->next = nextNode;
                hashtbl->nodes[hash] = node;
            }
            else if(strcmp(node->key, value)==0)
            {
                /* switch node positions if the key */
                nextNode->key = key;
                nextNode->tag = StringConst;
                nextNode->u.StringValue = value;
                node->next = NULL;
                nextNode->next = node;
                node = nextNode;
                hashtbl->nodes[hash] = nextNode;
            }
        }
        else
        {
            while(node)
            {
                struct hashnode_s *nextNode;
                nextNode = malloc(sizeof(struct hashnode_s));

                /* TESTING PURPOSES ONLY
                printf("#define %s %s\n",node->key,node->u.StringValue);
                printf("%s==%s\n",node->u.StringValue,key);
                printf("%s==%s\n\n\n",node->key, value);
                */

                if(strcmp(node->u.StringValue,key)==0)
                {
                    nextNode->key = key;
                    nextNode->tag = StringConst;
                    nextNode->u.StringValue = value;
                    nextNode->next = NULL;
                    node->next = nextNode;
                    return 0;
                }
                else if(strcmp(node->key, value)==0)
                {
                    nextNode->key = key;
                    nextNode->tag = StringConst;
                    nextNode->u.StringValue = value;
                    node->next = NULL;
                    nextNode->next = node;
                    node = nextNode;
                    return 0;
                }
                node = node->next;
            }
        }
    }
}

Но когда я добавляю элемент типа integer. По какой-то причине возникает ошибка сегментации?

Вот этот код.

int hashtbl_InsertValue(HASHTBL *hashtbl, const char *key, int integerValue)
{
    struct hashnode_s *node;
    hash_size hash;

    hash = SearchByKey(hashtbl, key);
    if(hash == -1)
    {
        hash=hashtbl->hashfunc(key);
    }

    if(hashtbl->nodes[hash] ==NULL)
    {
        node = malloc(sizeof(struct hashnode_s));
        node->key = key;
        node->tag = IntegerConst;
        node->u.IntegerValue = integerValue;
        node->next = NULL;
        hashtbl->nodes[hash] = node;
        return 0;
    }
    else
    {
        node = hashtbl->nodes[hash];
        //Check(hashtbl);
        while(node)
        {
            if(strcmp(node->u.StringValue,key)==0)
            {
                struct hashnode_s *nextNode;
                nextNode = malloc(sizeof(struct hashnode_s));

                nextNode->key = key;
                nextNode->tag = IntegerConst;

                nextNode->u.IntegerValue = 5;
                nextNode->next = NULL;

                if(node->next == NULL)
                {
                    // THIS IS WHERE IT CRASHES AT!
                    node->next = nextNode;
                }

                return 0;
            }
            node=node->next;
        }
    }
}

Я пытаюсь избавиться от ошибки сегментации, но у меня нет идей?

1 Ответ

0 голосов
/ 24 июня 2011

При рассмотрении вашего кода возникают некоторые непосредственные проблемы:

  1. Вы всегда выполняете strcmp со StringValue, даже если он объединен с IntegerValue, это означает, что strcmp будет читатьневерный адрес памяти и вызывает ошибку по умолчанию для целочисленных значений.
  2. Инициализирована ли ваша хеш-таблица, если нет, то вполне вероятно, что строка кода, на которую вы претендуете, является сегрегируемой, потому что это первая запись встраница без доступа для записи.
  3. Вы проверяете, равен ли NULL следующий узел, прежде чем назначать выделенный узел следующим узлом, если он выходит из строя, то вы не освобождаете память, эта утечка памяти может быть проблемой.Очевидное решение для числа 1, и это будет использовать следующий указатель NULL в качестве индикатора того, что вы достигли конца списка, а не проверять строку, которая не всегда может быть там.
  4. Хешявляется целым числом со знаком, убедитесь, что единственным отрицательным числом, возвращаемым из функции хеширования, является -1, поскольку любой другой отрицательный знак может легко быть другой недопустимой ошибкой доступа.

Если бы я был вами, то яУстраните эти другие проблемы, прежде чем пытаться отследить эту ошибку, проще найти ошибку, если вы ищете только одну.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...