简单的C链表程序可能存在内存问题



我正在尝试编写一个程序,该程序将计算段落中单词的出现次数。

我遵循的逻辑是:我使用的是链接列表。我正在按顺序搜索——如果遇到新单词在列表中添加单词,但如果单词已经存在于列表中,则增加其计数标志。

//case insensitive string matching
int strcicmp(char const *a, char const *b)
{
    int d;
    for(;;a++,b++)
    {
        d=tolower(*a)-tolower(*b);
        if(d!=0 || !*a)
            return d;
    }
}
//declare the linked list structure to store distinct words and their count
typedef struct node
{
    char *word;
    int count;
    struct node *next;
} node;
node *ptr, *newnode, *first=NULL, *last=NULL;
void insertnewword(char *ch)
{
    newnode=(node*)malloc(sizeof(node));
    if(newnode == NULL)
    {
        printf("nMemory is not allocatedn");
        exit(0);
    }
    else
    {
        newnode->word=ch;
        newnode->count=1;
        newnode->next=NULL;
    }           
    if(first==last && last==NULL)
    {
        first=last=newnode;
        first->next=NULL;
        last->next=NULL;
    }   
    else
    {
        last->next=newnode;     
        last=newnode;
        last->next=NULL;            
    }   
}
void processword(char *ch)
{   
    int found=0;
    //if word is already in the list, increase the count
    for(ptr=first;ptr!=NULL;ptr=ptr->next)          
        if(strcicmp(ptr->word, ch) == 0)
        {
            ptr->count += 1;
            found=1;
            break;
        }
    //if it's a new word, add the word to the list
    if(!found)
        insertnewword(ch);  
}
int main()
{
    const char *delimiters=" ~`!@#$%^&*()_-+={[}]:;<,>.?/|\'"tnr";
    char *ch, *str; 
    str=(char*)malloc(sizeof(char));
    ch=(char*)malloc(sizeof(char));
    //get the original string
    scanf("%[^n]%*c", str);
    //fgets(str, 500, stdin);
    //get the tokenized string
    ch=strtok(str,delimiters);
    while(ch!=NULL)
    {
        //a, an, the should not be counted
        if(strcicmp("a", ch)!=0 && strcicmp("an", ch)!=0 && strcicmp("the", ch)!=0)
            processword(ch);        
        ch=strtok(NULL,delimiters);
    }
    //print the word and it's occurrence count
    for(ptr=first; ptr!=NULL; ptr=ptr->next)
        printf("%stt%dn",ptr->word,ptr->count);
    return 0;
}

这似乎对少数单词有效,但如果单词计数超过6-7,则该程序会遇到一些问题。

说输入是:我是一个好男孩。我是个坏男孩。

输入应为

I 2上午2点良好1坏1男孩2

但我得到的是I 2上午2点良好1坏1(一些垃圾字符)1

对于同一个问题,我总是可以实现任何其他逻辑,但我想知道这个实现的问题。

提前感谢

我认为问题来自您的扫描f:

in the man scanf: the next pointer must be a pointer to char, and there must be enough room for all the characters in the string, plus a terminating null byte

但在main的顶部,char数组的分配只有一个长度:str=(char*)malloc(sizeof(char));

我认为使用getline 这样的功能会更好

ssize_t getline(char **lineptr, size_t *n, FILE *stream);并将lineptr设置为指向NULL

我认为你的链表实现并没有给你带来问题,但你的内存分配给你带来了实际的问题。

第一个内存分配问题:

str=(char*)malloc(sizeof(char));
ch=(char*)malloc(sizeof(char));

这里str和ch应该有内存来保存完整的单词和终止的null字符,但您只分配了一个字节(即char的大小)

第二个内存分配问题:

newnode->word=ch;

这个代码片段存在于insertnewword()函数中。在这里,您已经为新节点分配了内存,但没有为新节点内的字符分配任何内存。之后,直接使newnode->word指向ch,ch是main()函数的局部变量。当您完成第一个单词并进一步标记输入字符串时,ch包含字符串中的下一个单词。现在,这可能会破坏你的链接列表中的数据,因为你已经使newnode->word直接指向ch。

因此,请将内存分配给newnode中的单词字段,并将ch的内容复制到其中。

我希望这能解决你的问题。

相关内容

  • 没有找到相关文章