C 地址处映射区域的权限不正确

C 地址处映射区域的权限不正确,c,memory,valgrind,cs50,C,Memory,Valgrind,Cs50,我目前正在研究CS50x习题集5,拼写器。使用valgrind,我得到以下错误: ==395== Memcheck, a memory error detector ==395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==395== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==395== Command: ./s

我目前正在研究CS50x习题集5,拼写器。使用valgrind,我得到以下错误:

==395== Memcheck, a memory error detector
==395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==395== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==395== Command: ./speller texts/cat.txt
==395== 
==395== 
==395== Process terminating with default action of signal 11 (SIGSEGV)
==395==  Bad permissions for mapped region at address 0x601DE8
==395==    at 0x401155: add_Node (dictionary.c:75)
==395==    by 0x401239: load (dictionary.c:107)
==395==    by 0x400944: main (speller.c:40)
==395== 
==395== HEAP SUMMARY:
==395==     in use at exit: 5,328,336 bytes in 95,140 blocks
==395==   total heap usage: 95,141 allocs, 1 frees, 5,332,432 bytes allocated
==395== 
==395== 552 bytes in 1 blocks are still reachable in loss record 1 of 2
==395==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==395==    by 0x5258E49: __fopen_internal (iofopen.c:65)
==395==    by 0x5258E49: fopen@@GLIBC_2.2.5 (iofopen.c:89)
==395==    by 0x4011BE: load (dictionary.c:88)
==395==    by 0x400944: main (speller.c:40)
==395== 
==395== 5,327,784 bytes in 95,139 blocks are still reachable in loss record 2 of 2
==395==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==395==    by 0x401118: add_Node (dictionary.c:69)
==395==    by 0x401239: load (dictionary.c:107)
==395==    by 0x400944: main (speller.c:40)
==395== 
==395== LEAK SUMMARY:
==395==    definitely lost: 0 bytes in 0 blocks
==395==    indirectly lost: 0 bytes in 0 blocks
==395==      possibly lost: 0 bytes in 0 blocks
==395==    still reachable: 5,328,336 bytes in 95,140 blocks
==395==         suppressed: 0 bytes in 0 blocks
==395== 
==395== For counts of detected and suppressed errors, rerun with: -v
==395== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Segmentation fault
这是我的加载和添加节点函数代码:

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    FILE *file = fopen(dictionary, "r");

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

    // Set pointers in table to NULL
    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }
    
    char word[LENGTH + 1];  //to hold a word from dictionary
    
    while (fgets(word, LENGTH + 1, file) != NULL)
    {
        int row = hash(word);   // to determine where to store the word

        add_Node(row, word);
    }
    
    fclose(file);

    return true;
}

// Adds new node to a list in dictionary
void add_Node(int row, char word[LENGTH + 1])
{
    node *newNode = malloc(sizeof(node));
    strcpy(newNode->word, word);
    
    if (table[row] == NULL)  //if single linked list is empty
    {
        table[row] = newNode;
    }
    else
    {
        node *tmpHead = table[row];   
        table[row] = newNode;
        newNode->next = tmpHead;
    }
}
第105行对应于以下内容中的“表[行]=newNode;”:


table是一个全局变量,是node类型的指针数组。我已经验证了行是否确实在数组table的范围内。我不知道如何解决这个问题。问题可能是什么?

首先让我们使用change
while(fgets(word,LENGTH+1,file)!=NULL)
while(fscanf(file,“%s”,word)!=EOF)
,因为您没有阅读
“\n”

您的
add_节点
函数缺少某些行,需要进行一些更改:

旧版:

// Adds new node to a list in dictionary
void add_Node(int row, char word[LENGTH + 1])
{
    node *newNode = malloc(sizeof(node));
    strcpy(newNode->word, word);
    
    if (table[row] == NULL)  //if single linked list is empty
    {
        table[row] = newNode;
    }
    else
    {
        node *tmpHead = table[row];   
        table[row] = newNode;
        newNode->next = tmpHead;
    }
}
// Adds new node to a list in dictionary

void add_Node(int row, char word[LENGTH + 1])
{
    node *newNode = malloc(sizeof(node));
    //Test if the node is not empty
    if(newNode == NULL){
        return 1;
    }

    strcpy(newNode->word, word);
    newNode->next = NULL;
    
    if (table[row] == NULL)  //if single linked list is empty
    {
        table[row] = newNode;
    }
    else
    {   //Set the newNode to table at row and make table[row]
        //equal to newNode to overwrite the current address at table[row]. 
        //No need for tmp as we are not swapping things.
        newNode -> next = table[row];
        table[row] = newNode;
    }
}
新建:

// Adds new node to a list in dictionary
void add_Node(int row, char word[LENGTH + 1])
{
    node *newNode = malloc(sizeof(node));
    strcpy(newNode->word, word);
    
    if (table[row] == NULL)  //if single linked list is empty
    {
        table[row] = newNode;
    }
    else
    {
        node *tmpHead = table[row];   
        table[row] = newNode;
        newNode->next = tmpHead;
    }
}
// Adds new node to a list in dictionary

void add_Node(int row, char word[LENGTH + 1])
{
    node *newNode = malloc(sizeof(node));
    //Test if the node is not empty
    if(newNode == NULL){
        return 1;
    }

    strcpy(newNode->word, word);
    newNode->next = NULL;
    
    if (table[row] == NULL)  //if single linked list is empty
    {
        table[row] = newNode;
    }
    else
    {   //Set the newNode to table at row and make table[row]
        //equal to newNode to overwrite the current address at table[row]. 
        //No need for tmp as we are not swapping things.
        newNode -> next = table[row];
        table[row] = newNode;
    }
}

这将解决你的valgrind问题。此外,您不需要tmp节点,因为这不是必需的。我不确定您的
hash
函数是否运行良好,但我认为这很好。最后一件事,在
加载
功能结束时关闭
fclose(file)
,因为根据valgrind,这将导致“可访问”内存泄漏。

这是valgrind错误的完整列表吗?此外,这是一个分段错误。您是否初始化了
?@n.“代词m”<代码>表格已初始化您还忘记了
newNode->next=NULL
,@AbdelrahmanRagab代替
fgets()
使用
fscanf
。所以这个
while(fgets(word,LENGTH+1,file)!=NULL)
会变成
while(fscanf(file,“%s”,word)!=EOF)