我该如何解决代码中的细分错误

时间:2020-05-02 07:00:33

标签: cs50

嗨,我正在从cs50的问题集5中进行拼写检查,遇到了分段错误,但是我不明白为什么。我得到的错误是这样的:

MISSPELLED WORDS

==18659== Invalid read of size 8
==18659==    at 0x40102C: check (dictionary.c:32)
==18659==    by 0x400C49: main (speller.c:112)
==18659==  Address 0x75cfc8 is not stack'd, malloc'd or (recently) free'd
==18659== 
==18659== 
==18659== Process terminating with default action of signal 11 (SIGSEGV)
==18659==  Access not within mapped region at address 0x75CFC8
==18659==    at 0x40102C: check (dictionary.c:32)
==18659==    by 0x400C49: main (speller.c:112)
==18659==  If you believe this happened as a result of a stack
==18659==  overflow in your program's main thread (unlikely but
==18659==  possible), you can try to increase the size of the
==18659==  main thread stack using the --main-stacksize= flag.
==18659==  The main thread stack size used in this run was 8388608.
==18659== 
==18659== HEAP SUMMARY:
==18659==     in use at exit: 552 bytes in 1 blocks
==18659==   total heap usage: 4 allocs, 3 frees, 6,224 bytes allocated
==18659== 
==18659== 552 bytes in 1 blocks are still reachable in loss record 1 of 1
==18659==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18659==    by 0x5258E49: __fopen_internal (iofopen.c:65)
==18659==    by 0x5258E49: fopen@@GLIBC_2.2.5 (iofopen.c:89)
==18659==    by 0x4009E3: main (speller.c:55)
==18659== 
==18659== LEAK SUMMARY:
==18659==    definitely lost: 0 bytes in 0 blocks
==18659==    indirectly lost: 0 bytes in 0 blocks
==18659==      possibly lost: 0 bytes in 0 blocks
==18659==    still reachable: 552 bytes in 1 blocks
==18659==         suppressed: 0 bytes in 0 blocks
==18659== 
==18659== For counts of detected and suppressed errors, rerun with: -v
==18659== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
/etc/profile.d/cli.sh: line 94: 18659 Segmentation fault      valgrind ./speller texts/cat.txt

这是我的代码:

// Implements a dictionary's functionality

#include <stdbool.h>
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
#include <string.h>
#include "dictionary.h"

// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

int word_count;

// Number of buckets in hash table
const unsigned int N = 1;

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // Hash word to obtain hash value
    int index = hash(word);
    // Access linked list at that index
    node* cursor = table[index];
    while(cursor != NULL)
    {
        if(strcasecmp(word, cursor->word) == 0)
        {
            return true;
        }
        // Traverse linked list
        else
        {
            cursor = cursor->next;
        }
    }
    return false;
}

// Hashes word to a number
//Hash table that I got from https://stackoverflow.com/questions/7666509/hash-function-for-string
unsigned int hash(const char *word)
{
    unsigned int hash = 5381;
    int c;

    while ((c = *word++))
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

    return hash;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Open dictionary file
    FILE* memory = fopen(dictionary, "w");
    word_count = 0;
    if(memory == NULL)
    {
        return false;
    }
    char word[LENGTH + 1];
    while((fscanf(memory, "%s", word) != EOF))
    {
        node* n = malloc(sizeof(node));
        if(n == NULL)
        {
            return false; 
        }
        strcpy(n->word, word);
        word_count++;
        int index = hash(n->word);
        // Inserting into start of linked lists with no elements
        if(table[index]->next == NULL)
        {
            table[index] = n;
        }
        //Inserting into start of linked lists with elements
        else
        {
            n->next = table[index];
            table[index] = n;
        }
        
        
    }
    
    
    fclose(memory);
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    return word_count;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    int counter = 0;
    for(int i = 0; i < N; i++)
    {
        while(table[i] != NULL)
        {
            node* temp = table[i]->next;
            free(table[i]);
            table[i] = temp;
        }
        counter++;
    }
    if(counter == N)
    {
        return true;
    }
    return false;
}

我不明白为什么会出现分段错误,因为我提供了一个while循环来在光标位于循环末尾时停止。有人可以告诉我我哪里出问题了吗?谢谢!

1 个答案:

答案 0 :(得分:0)

您的问题似乎在这里发生:

from selenium import webdriver
import selenium

driver = webdriver.Chrome(r"C:\Users\007\Desktop\chromedriver_win32\chromedriver.exe")

driver.get("http://www.python.org")

具体地说,查看您的哈希函数,似乎并没有采取任何措施来确保哈希在表大小 int index = hash(word); // Access linked list at that index node* cursor = table[index]; 之内。这意味着当您对单词进行哈希运算时,N可能大于index,随后对表的索引访问将导致您的错误。

尝试从哈希函数返回N