Linked List - C - 从节点指针数组中正确访问struct节点的值

时间:2014-04-11 04:20:38

标签: c linked-list

第一篇文章,在编码知识方面极为有限,对C来说是新手。温柔!我正处于"尝试"不同的事情让我越来越困惑。我需要有人正确的指导!

这个特殊的问题来自于我正在尝试的在线edX课程,最终在正确实施时,检查从文本文件中读入的给定单词('检查'功能)并将其与每个单词读取进行比较进入(来自'加载'函数)结构的链接列表。

我相信我正确地实现了加载功能,就像我使用gdb一样,因为我看到了我期待的内容,但我的问题和我的问题特别与检查功能有关。我仍然需要很多工具来完成我的代码,但在使用gdb进行测试时,我没有看到结构的char *成员的值与我预期的应该看到的相符。

  1. 使用gdb并单步执行'检查'函数并尝试访问我在load函数中创建的链表中的struct节点的dword成员,我预计我应该看到char *成员的字符串。例如,我期待“" cat"分配给current->dword,但我在测试时看到gdb:

    〜(gdb)print current-> dword

    $ 13 = 0xbfffede2" \ 004 \ b \ 214 \ 365 \ 372D \ 300 \ 355 \ 377 \ 277"

  2. 我的想法是,我仍然只是以某种方式访问​​某个地址而不是实际值,但我不知道为什么会这样。在load函数中创建节点时,会正确地为dword成员分配一个值(至少在我单步执行gdb中的代码时可以告诉),但似乎无法访问正确地在检查功能。任何新手的帮助都将不胜感激!

        #include <ctype.h>
        #include <stdbool.h>
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
    
        #include "dictionary.h"
    
        typedef struct node
        {
            char* dword;
            struct node* next;
        }
        node;
    
        // keep track of #of words in dictionary loaded
        int wordCounter = 0;
    
        // create root for hash table
        node* root[26];
    
        // create cursor to keep place in creating, pointing, and traversing through nodes
        node* current = NULL;
    
        /**
         * Returns true if word is in dictionary else false.
         */
        bool check(const char* word)
        {
            // size of word read into buffer
            int wordSize = sizeof(word);
    
            // prepare to make a new lowercase only word for comparison to lowercase only dictionary
            char bufWord[wordSize];
    
            // make it
            for(int i = 0; i < wordSize; i++)
            {   
                if (i == wordSize - 1)
                {
                    bufWord[i] = '\0';
                }
    
                else
                {
                    bufWord[i] = tolower(word[i]);
                }
            }
    
            // hash word to achieve proper root node location
            int hash = bufWord[0] - 97;
    
            // point to the correct root node to begin traversing
            current = root[hash];
    
            // make sure there is even a word in hash table location
            if(root[hash] == NULL)
            {
                return false;
            }
    
            else if(root[hash] != NULL)
            {
                // progress through the nodes until the last node's next pointer member is NULL
                while(current != NULL)
                {
                    // compare 1st letter only of current->dword[i] to bufWord[i] to save time
    
                        // if they don't match, return false
    
                        // if they do match then continue
        \
                    char dictWord[wordSize];
    
                    // hold copy of struct member value to compare to dictWord
                    char* wordTemp = current->dword;
    
                    // 
                    for(int i = 0; i < wordSize; i++)
                    {   
                        dictWord[i] = wordTemp[i];
                    }
    
                    // do a spell check
                    if(strcmp(bufWord, dictWord) == 0)
                    {
                        return true;
                    }
    
                    else
                    {
                        // set current to the next node if any or NULL if it's already the last node in the list
                        current = current->next;
                    }
                }    
            }
    
            return false;
        }
    
        /**
         * Loads dictionary into memory.  Returns true if successful else false.
         */
        bool load(const char* dictionary)
        {   
            // buffer for reading in dictionary words
            char wordIn[LENGTH + 1];
    
            // open the dictionary file
            FILE* newDict = fopen(dictionary, "r");
    
            for (int i = 0; i < 27; i++)
            {
                root[i] = NULL;
            }
    
            // while there are words to read
            while(fscanf(newDict, "%s ", wordIn) > 0)
            {
    
                // keep track of #of words for constant time read in size function
                wordCounter++;
    
                // hash the first letter for the location in root
                int hash = wordIn[0] - 97;
    
                // malloc space for a new node
                node* newNode = malloc(sizeof(node));
    
                // error check
                if (newNode == NULL)
                {
                    return false;
                }
    
                // set value member of node to current word
                newNode->dword = wordIn;
    
                // first insertion into linked list if that root node has not been used yet 
                if(root[hash] == NULL)
                {
                    // sets to NULL
                    newNode->next = root[hash];
    
                    // link it
                    root[hash] = newNode;
                }
    
                else if(root[hash] != NULL)
                {
                    // starts at the root
                    node* current = root[hash];
    
                    // insert into new beginning of list
                    newNode->next = current;
                    root[hash] = newNode;
                }
            }
    
            fclose(newDict);
            return true;
        }
    
        /**
         * Returns number of words in dictionary if loaded else 0 if not yet loaded.
         */
        unsigned int size(void)
        {
            return wordCounter;
        }
    
        /**
         * Unloads dictionary from memory.  Returns true if successful else false.
         */
        bool unload(void)
        {
            // TODO
            return false;
        }
    

1 个答案:

答案 0 :(得分:1)

您的问题的根源是:

newNode->dword = wordIn;

wordInload中的本地数组。您将wordIn的地址存储在节点的dword中。当您从load返回时,这些地址将不再有效。

您需要做的是为wordIn中的字符串分配内存,将分配的内存分配给newNode->dword并将wordIn的内容复制到newNode->dword

如果您的平台提供非标准功能strdup,您可以将以上行更改为:

newNode->dword = strdup(wordIn);

如果没有,则很容易实现:

char* strdup(char const* in)
{
   char* r = malloc(strlen(in)+1);
   strcpy(r, in);
   return r;
}