无法在函数中使用全局指针访问结构/全局指针在递归中不起作用?

问题描述 投票:0回答:0

抱歉打扰,但我不明白为什么代码不起作用。如果我使用全局指针调用函数,它会传递地址,但当我尝试转到下一个节点时,它只会返回 (nil)。此外,如果我在生成函数中打印下一个节点的指针,它也可以正常工作。那么发生了什么?

Info: length = 1, tmp_word = a, line 214 or ctrl + f nil.

// Implements a dictionary's functionality
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <string.h>

#include "dictionary.h"

// Load variables:
char *dict_word;
FILE *dict;

// Size variables:
unsigned int count_words = 0;

// Structure
const int nodes = 27; // 26 letters + '.
int heigth = 3;

typedef struct hash_table
{
    char word[46]; // 45 letters + NULL.
    struct hash_table *next;
}
hash_table;

typedef struct trie
{
    bool is_word;
    struct trie *character[nodes];
    hash_table *next;
}
trie;

trie *root;

// Generate structure.
trie *generate(int times);

// Assign to the structure created.
void hash_(trie *any);
void assign(trie *any, int length, int index, char *tmp_word);
void assign_v2(trie *any, int heigth_b, int index, char *tmp_word);
void assign_v2b(hash_table *any, char *tmp_word);

// Free.
void free_hashtable(trie *any, int times);
void free_hashtable2(hash_table *any);
void free_trie(trie *any);

// Check.
bool check_trie(const char *word, int length, trie *any, int index);
bool check_trie_v2(const char *word, int length, trie *any, int index);
bool check_hash(const char *word, hash_table *any);

// Returns true if word is in dictionary, else false
bool check(const char *word)
{
    int length = strlen(word);

    if (length <= 3)
    {
        return check_trie(word, length, root, 0);
    }

    else if (length > 3)
    {
        return check_trie_v2(word, heigth, root, 0);
    }

    return false;
}

// DONE
bool load(const char *dictionary)
{
    dict = fopen(dictionary, "r");
    if (dict == NULL)
    {
        printf("Could not load the file\n");
        return false;
    }

    if (fseek(dict, 0, SEEK_END) == -1)
    {
        return false;
    }

    long x;
    if ((x = ftell(dict)) == - 1)
    {
        return false;
    }
    rewind(dict);

    dict_word = malloc(x);
    if (dict_word == NULL)
    {
        return false;
    }

    fread(dict_word, 1, x, dict);

    root = generate(3);
    hash_(root);

    return true;
}

// DONE
unsigned int size(void)
{
    if (count_words != 0)
    {
        return count_words;
    }
    else
    {
        return 0;
    }
}

bool unload(void)
{
    free(dict_word);
    free_hashtable(root, heigth);
    free_trie(root);
    free(root);

    if (fclose(dict)!= 0)
    {
        return false;
    }

    else
    {
        return true;
    }
}

trie *generate(int times)
{
    // Allocate memory to root, to character[i]
    // and also change the access of character[i] to root.
    // So in the second run, root would be equivalent to
    // root->character[i].
    root = malloc(sizeof(trie));
    root->next = NULL;

    if (times > 0)
    {
        for (int i = 0; i < nodes; i++)
        {
            // For every single pointer generates more nodes pointers.
            root->character[i] = generate(times - 1);
        }
    }

    else
    {
        for (int i = 0; i < nodes; i++)
        {
            // Set all remaining pointers to null
            // as there aren't more arrays.
            root->character[i] = NULL;
        }
        // Malloc for new structure.
        root->next = malloc(sizeof(hash_table));
        root->next->next = NULL;
    }

    // Return the address of root,
    // so the root in the main function can point
    // to the trie created.
    return root;
}

void hash_(trie *any)
{
    char *tmp_word = calloc(1, 46);
    char c;

    int length = 0;

    for (int i = 0; dict_word[i] != '\0'; i++)
    {
        c = dict_word[i];
        strncat(tmp_word, &c, 1);

        if (dict_word[i + 1] == '\n')
        {
            length = strlen(tmp_word);

            if (length <= heigth)
            {
                assign(root, length, 0, tmp_word);
                free(tmp_word);
                i++;
            }

            else
            {
                assign_v2(root, heigth, 0, tmp_word);
                free(tmp_word);
                i++;
            }
        }
    }
}

void assign(trie *any, int length, int index, char *tmp_word)
{
    printf("%p\n", any); // root
    printf("%p\n", any->character[0]); // nil

    if (length != 0)
    {
        if (tmp_word[index] != '\'')
        {
            assign(any->character[1], length - 1, index + 1, tmp_word);
        }
        else
        {
            assign(any->character[26], length - 1, index + 1, tmp_word);
        }
    }

    any->is_word = 1 // nil, core dump

    return;
}

void assign_v2(trie *any, int heigth_b, int index, char *tmp_word)
{
    if (heigth_b != 0)
    {
        if (tmp_word[index] != '\'')
        {
            assign_v2(any->character[tmp_word[index] - 97], heigth_b - 1, index + 1, tmp_word);
        }
        else
        {
            assign_v2(any->character[26], heigth_b - 1, index + 1, tmp_word);
        }
    }

    else
    {
        assign_v2b(any->next, tmp_word);
        return;
    }
}

void assign_v2b(hash_table *any, char *tmp_word)
{
    // Create a tmp pointer to last word.
    hash_table *tmp = any;

    // Malloc and assign new word.
    hash_table *new = malloc(sizeof(hash_table));
    strcpy(new->word, tmp_word);

    // Make root point to the same location as new_word.
    any = new;

    // Move first word to the right.
    any->next = tmp;

    return;
}

void free_hashtable(trie *any, int times)
{
    for (int i = 0; i < nodes; i++)
    {
        if (times > 1)
        {
            free_hashtable(any->character[i], times - 1);
        }
    }
    if (times == 1)
    {
        for (int i = 0; i < nodes; i++)
        {
            //Where root is root->character[i]->character[i]
            if (any->character[i]->next->next != NULL)
            {
                free_hashtable2(any->character[i]->next);
            }
            free(any->character[i]->next);
        }
    }
    return;
}

void free_hashtable2(hash_table *any)
{
    if (any->next != NULL)
    {
        free_hashtable2(any->next);
        free(any->next);
    }
    return;
}

void free_trie(trie *any)
{
    for (int i = 0; i < nodes; i++)
    {
        if (any->character[i] != NULL)
        {
            // Calls function first so it can works backwards.
            free_trie(any->character[i]);
            free(any->character[i]);
        }
    }
    return;
}

bool check_trie(const char *word, int length, trie *any, int index)
{
    if (length != 0)
    {
        if (word[index] == '\'')
        {
            check_trie(word, length - 1, any->character[26], index + 1);
        }

        else if (isupper(word[index]) != 0)
        {
            check_trie(word, length - 1, any->character[word[index] - 65], index + 1);
        }

        else if (islower(word[index]) != 0)
        {
            check_trie(word, length - 1, any->character[word[index] - 97], index + 1);
        }
    }

    if (any->is_word == 1)
    {
        return true;
    }
    else

    {
        return false;
    }
}

bool check_trie_v2(const char *word, int length, trie *any, int index)
{
    if (length != 0)
    {
        if (word[index] == '\'')
        {
            check_trie_v2(word, length - 1, any->character[26], index + 1);
        }

        else if (isupper(word[index]) != 0)
        {
            check_trie_v2(word, length - 1, any->character[word[index] - 65], index + 1);
        }

        else if (islower(word[index]) != 0)
        {
            check_trie_v2(word, length - 1, any->character[word[index] - 97], index + 1);
        }
    }

    return check_hash(word, any->next);
}

bool check_hash(const char *word, hash_table *any)
{
    if (any != NULL)
    {
        if (strcmp(word, any->word) == 0)
        {
            return true;
        }

        else
        {
            check_hash(word, any->next);
        }
    }

    if (any == NULL)
    {
        return false;
    }

    return false;
}

程序在第 231 行得到一个核心转储

对不起,有点乱。谢谢!

我试着用关/开做一个迷你功能。该函数接受一个新的 int 值 1。然后我做了 any = root 和 on = 0。因为我确实认为这个问题在某种程度上与函数参数的全局变化有关,但它没有用。

c function pointers recursion global-variables
© www.soinside.com 2019 - 2024. All rights reserved.