Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我的节点都没有被释放?(cs50 pset5分段故障)C_C_Memory Leaks_Segmentation Fault_Cs50 - Fatal编程技术网

为什么我的节点都没有被释放?(cs50 pset5分段故障)C

为什么我的节点都没有被释放?(cs50 pset5分段故障)C,c,memory-leaks,segmentation-fault,cs50,C,Memory Leaks,Segmentation Fault,Cs50,我在哈佛cs50课程的pset5中实现加载和卸载函数时遇到问题。当我运行它时,我得到一个分段错误,当我运行valgrind时,它告诉我在加载时malloc的所有节点都没有被释放 几天来我一直在尝试解决这个问题,我尝试了几种不同的卸载函数实现,但都没有效果。我想错误可能在我的加载函数中。谁能帮我拿这个吗 /**************************************************************************** * dictionary.c *

我在哈佛cs50课程的pset5中实现加载和卸载函数时遇到问题。当我运行它时,我得到一个分段错误,当我运行valgrind时,它告诉我在加载时malloc的所有节点都没有被释放

几天来我一直在尝试解决这个问题,我尝试了几种不同的卸载函数实现,但都没有效果。我想错误可能在我的加载函数中。谁能帮我拿这个吗

 /****************************************************************************
 * dictionary.c
 *
 * Computer Science 50
 * Problem Set 5
 *
 * Implements a dictionary's functionality.
  ***************************************************************************/

 #include <stdbool.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <math.h>
 #include <string.h>

 #include "dictionary.h"

 #define HASHTABLE_SIZE 5000

 // create word counter for size
 int wordCount = 0;

 // linked link struct
 typedef struct node
 {
     // word's length + NULL character
     char word[LENGTH + 1];
     struct node* next;
 }
 node;

 // Hashtable array
 node* hashtable[HASHTABLE_SIZE];


 // hash function from study.cs50.net
 int hash_function(char* key)
 {
     // initialize index to 0
     int index = 0;   

     // sum ascii values
     for (int i = 0; key[i] != 0; i++)
     {
         index += toupper(key[i]) - 'A';
     }

     return index % HASHTABLE_SIZE;
 }

 /**
  * Returns true if word is in dictionary else false.
  */
 bool check(const char* word)
 {
     // create variable to hold word
     char temp[LENGTH + 1];

     // convert every character in word to lowercase
     for (int i = 0, n = strlen(word); i < n; i++)
     {
         if (isalpha(word[i]))
         {
             temp[i] = tolower(word[i]);  
         } 
     }

     // get hashed word's index
     int hash_index = hash_function(temp);

     // find head of that index
     node* head = hashtable[hash_index];


     // traverse through linked list 
     for (node* cur = head; cur != NULL; cur = cur->next)
     {
         // find if linnked list contains word
         if (strcmp(cur->word, word) == 0)
         {
             return true;
         }   
     }  

     return false;
 }

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

     // check if file exists
     if (file == NULL)
     {
         return false;
     }

     // word length plus NULL character
     char word[LENGTH + 1];

     // iterate through every word of the dictionary
     while (fscanf(file, "%s\n", word) != EOF) // Source: http://stackoverflow.com/questions/6275558/question-about-whileeof
          {
              node* new_node = malloc(sizeof(node));

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

         wordCount++;

         strcpy(new_node->word, word);  // Source: cs50 reddit

         int hash_index = hash_function(new_node->word);

         // check whether node should be head
         if (hashtable[hash_index] == NULL)
         {
             hashtable[hash_index] = new_node;
             new_node->next = NULL;
         }

         else
         {
             new_node->next = hashtable[hash_index];
             hashtable[hash_index] = new_node; 
         }    
     }
     // close file
     fclose(file);

     return false;
 }

 /**
  * Returns number of words in dictionary if loaded else 0 if not yet loaded.
  */
 unsigned int size(void)
 {

     return wordCount;
 }

 /**
  * Unloads dictionary from memory.  Returns true if successful else false.
  */
 bool unload(void)
 {   
     // go through all of the indexes in the hashtable 
     for (int i = 0; i < HASHTABLE_SIZE; i++)
     {
         node* head = hashtable[i];

         while (head != NULL)
         {
             node* ptr = head->next;

             free(head);
             head = ptr;
         }   
     }   
     return true;
 }
/****************************************************************************
*字典
*
*计算机科学50
*习题集5
*
*实现字典的功能。
***************************************************************************/
#包括
#包括
#包括
#包括
#包括
#包括
#包括“dictionary.h”
#定义哈希表大小5000
//为大小创建单词计数器
int字数=0;
//链接结构
类型定义结构节点
{
//单词长度+空字符
字符字[长度+1];
结构节点*下一步;
}
节点;
//哈希表数组
节点*哈希表[哈希表大小];
//study.cs50.net中的哈希函数
int散列函数(字符*键)
{
//将索引初始化为0
int指数=0;
//ascii值总和
对于(int i=0;键[i]!=0;i++)
{
索引+=toupper(键[i])-‘A’;
}
返回索引%HASHTABLE\u大小;
}
/**
*如果单词在字典中,则返回true,否则返回false。
*/
布尔检查(常量字符*单词)
{
//创建用于保存word的变量
字符温度[长度+1];
//将word中的每个字符转换为小写
for(int i=0,n=strlen(word);inext)
{
//查找链接列表是否包含word
if(strcmp(cur->word,word)==0)
{
返回true;
}   
}  
返回false;
}
/**
*将字典加载到内存中。如果成功,则返回true;否则返回false。
*/
布尔加载(常量字符*字典)
{
////打开文件
FILE*FILE=fopen(字典,“r”);
//检查文件是否存在
if(file==NULL)
{
返回false;
}
//字长加空字符
字符字[长度+1];
//反复阅读字典中的每个单词
while(fscanf(文件,“%s\n”,word)!=EOF)//来源:http://stackoverflow.com/questions/6275558/question-about-whileeof
{
node*new_node=malloc(sizeof(node));
if(新节点==NULL)
{
返回false;
}
字数++;
strcpy(new_node->word,word);//来源:cs50 reddit
int hash_index=hash_函数(新节点->单词);
//检查节点是否应为头部
if(哈希表[哈希索引]==NULL)
{
哈希表[哈希索引]=新的\u节点;
新建节点->下一步=空;
}
其他的
{
新建节点->下一步=哈希表[哈希索引];
哈希表[哈希索引]=新的\u节点;
}    
}
//关闭文件
fclose(文件);
返回false;
}
/**
*如果已加载,则返回字典中的字数;如果尚未加载,则返回0。
*/
无符号整数大小(void)
{
返回字数;
}
/**
*从内存中卸载字典。如果成功,则返回true;否则返回false。
*/
bool卸载(无效)
{   
//检查哈希表中的所有索引
for(int i=0;inext;
自由(头);
水头=ptr;
}   
}   
返回true;
}

您的
卸载功能良好。代码的问题在于
check
功能,尤其是您试图将输入转换为小写的部分:

char temp[LENGTH + 1];

for (int i = 0, n = strlen(word); i < n; i++)
{
    if (isalpha(word[i]))
    {
        temp[i] = tolower(word[i]);  
    } 
}
chartemp[长度+1];
for(int i=0,n=strlen(word);i
这里有两个问题。首先,
temp
不是以null结尾的。其次,检查
isalpha
意味着您可以不初始化字符:如果您的输入是,比如说,
“我”
temp
将保存
'I'
,垃圾,
'm'
,垃圾,当它应该保存
'I'
'm'
'0'
,垃圾

或者,您可以过滤掉不需要的字符。在这种情况下,您需要两个索引:一个用于源单词,另一个用于过滤单词

但您甚至不需要这个额外的步骤,因为哈希函数再次将输入转换为
toupper

说到你的散列函数:你可能想选择一个更好的。当前的一个不能很好地将值分布在5000个插槽上。(当你在0到25之间添加最多20个数字时,你怎么能达到5000?)


散列还有另一个问题:如果您输入一个数字,则贡献的“字母”为负数,因为在ASCII中,数字的值为48到57,您从中减去
'a'
,65的值。通常,哈希函数应该返回一个无符号值。

在调试器下运行此函数时,您发现了什么?“free”的点击次数是否与“malloc”的点击次数相同?请显示您的
main
函数和/或驱动整个程序的其他代码。否则,我们甚至不知道您是否正在调用
unload
(我并不是说您没有,但在StackOverflow上,简单的错误并不少见)