C中的分段错误

时间:2014-04-23 09:36:49

标签: c list segmentation-fault alphabetical

该程序将按字母顺序从文本创建链接列表 它区分大小写,它将消除标记。

当我运行程序时,它会产生分段错误。我无法找到问题所在。我添加了printf()以便找到错误,但我不能。

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

typedef struct NODE {
    char *word;
    int count;
    struct NODE *next;
}NODE;

char *get_word(FILE *fp){
     printf("getWord");
     char *str = (char*)malloc(sizeof(char)*100);

     char c;
     do {
        c = fgetc(fp);
        if (c == EOF) 
            return 0;
        } while (!isalpha(c));
        do {
             printf("getWord");

        *str++ = tolower(c);
        c = fgetc(fp);
        printf("Word");

        } while (isalpha(c));

        return str;
        }

void insert(NODE* sortedList, char *word) { 
   printf("INSERT ");

   char *str = (char*)malloc(sizeof(char)*100);
   if (sortedList == NULL || word < sortedList->word) {

      NODE *ekle;
      ekle=(NODE*)malloc(sizeof(NODE));
      strcpy(ekle->word,word);
      ekle->count = 1;
      ekle->next = sortedList;
      sortedList = ekle;
   }
   else {
        // 
      NODE *current = sortedList->next;
      NODE *pre = sortedList;
      while (current != NULL && word > current->word) { 
         pre = current;
         current = current->next;
      }
      if (current != NULL && word == current->word) {

         (current->count)++;
      }
      else {

         NODE *ekle;
         ekle=(NODE*)malloc(sizeof(NODE));
         strcpy(ekle->word,word);
         ekle->count = 1;
         ekle->next = current;
         pre->next = ekle;
      }
   }
}

void createList(FILE* fp,NODE *n) {
   printf("CREATELIST ");
   char *word;
   strcpy(word,get_word(fp));
   puts(word);
   while (strcmp(word,"")) {
      printf("Create_LİST2");
      insert(n,word);
      word = get_word(fp);
   }
}

NODE *head;


int main(){
    NODE *list=NULL;;
    FILE *fp;
    fp=fopen( "text.txt", "r" );
    head=list;

    while(!feof(fp)){

                     createList(fp,list);

                     }
    while(list->next != NULL){
                     printf("%s", list->word);
                     }
    return 0;
}

6 个答案:

答案 0 :(得分:3)

一个主要问题是这一行

*str++ = tolower(c);

这会更改指针str,因此当您从函数返回str时,它实际上将指向字符串。顺便说一句,你不会终止的字符串。

另一个主要问题是这些问题:

NODE *ekle;
ekle=(NODE*)malloc(sizeof(NODE));
strcpy(ekle->word,word);

这里分配NODE结构,但不为ekle->word分配内存,因此它指向不确定的内存。你有两个地方的上述代码。

等于上述分配问题,你有

char *word;
strcpy(word,get_word(fp));

这里也没有为word分配内存,所以你有一个指向不确定内存的指针。


另外,在C you should not cast the return of malloc中。您还应该注意编译器发出的警告,如果您没有从代码中获取任何警告,则需要启用更多警告。编译器警告通常是undefined behavior的标志,这就是上述所有内容。最后,在编译器旁边,我认为调试器是开发人员最好的工具。学会使用它,它可以帮助你解决上述一些问题。

答案 1 :(得分:2)

这是一个问题:

char c;
do {
    c = fgetc(fp);
    if (c == EOF) 
        return 0;

这是错的; fgetc()返回int,因为EOF不适合char。因此第一行应该是:

int c;

答案 2 :(得分:0)

不是段错误,而是:你malloc str,不使用或释放​​它

void insert(NODE* sortedList, char *word) { 
  printf("INSERT ");
  char *str = (char*)malloc(sizeof(char)*100);

答案 3 :(得分:0)

您必须验证文件是否正确打开。然后AFAIK strcpy要求目的地有足够的空间来存储数据(第74行),而不是&#34; char * word&#34;使用&#34;字符[255]&#34;例如(如果您知道大小限制)。

答案 4 :(得分:0)

您的主要问题在于:

*str++ = tolower(c);

首先,一旦增加str,就不再拥有指向动态分配内存的指针。因此,您将无法在程序执行的稍后时间释放该内存,这最终会导致内存泄漏。其次,当你在函数末尾返回str时,你返回指向该字符串的指针,正如你可能希望的那样。

其他问题包括:

  1. 您无法确保存储的字符数不超过99个。
  2. 您没有使用空字符终止str指向的字符串。
  3. 如果遇到str,您不会取消分配EOF指向的字符串。
  4. 您没有使用int来存储函数fgetc的返回值。
  5. 以下是您的功能应如下所示:

    #define MAX_WORD_LEN 101
    
    char* get_word(FILE* fp)
    {
        char* str = (char*)malloc(sizeof(char)*MAX_WORD_LEN);
        int c,i;
        do
        {
            c = fgetc(fp);
            if (c == EOF)
            {
                free(str);
                return 0;
            }
        }
        while (!isalpha((char)c));
        i = 0;
        do
        {
            str[i++] = tolower((char)c);
            c = fgetc(fp);
        }
        while (isalpha((char)c) && i < MAX_WORD_LEN-1);
        str[i] = 0;
        return str;
    }
    

    请注意,如果文件中的单词长度超过MAX_WORD_LEN-1个字符,那么您将基本上“丢失”最后读取的字符,因为它不会存储在任何位置。

答案 5 :(得分:0)

在这里,我编写的代码可以帮助您理解问题。它与您的程序的功能并不完全相同,但有些类似且更容易理解,并且还可以从以下代码中找到所有问题解决方案:

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

typedef struct NODE
{
   char word[100];
   int count;
   struct NODE *next;
}NODE;

NODE *head = NULL;
NODE *list = NULL;

void insert(char *word)
{
   if (list == NULL)
   {
      list = calloc(1, sizeof(NODE));
      if (NULL == list)
      {
         perror("Memory allocation failed");
         return;
      }
      strncpy(list->word, word, 99);
      list->count = 1;
      list->next = NULL;
      head = list;
   }
   else
   {
      list->next = calloc(1, sizeof(NODE));
      if (NULL == list->next)
      {
         perror("Memory allocation failed");
         return;
      }
      strncpy(list->next->word, word, 99);
      list->next->count = 1;
      list->next->next = NULL;
      list = list->next;
   }
}

void createList(FILE* fp)
{
   char word[100] = {0};
   while (EOF != fscanf(fp, "%99s", word))
   {
      if (0 < strlen(word))
      {
         insert(word);
      }
      memset(word, 0x00, 100);
   }
}

int main()
{
   FILE *fp = NULL;
   fp = fopen("text.txt", "r");
   if (NULL == fp)
   {
      //File is not readable
      perror("text.txt file open failed");
      return -1;
   }

   createList(fp);

   list = head;
   while(NULL != list)
   {
      printf("%s\n", list->word);
      list = list->next;
   }

   if (NULL != fp)
   {
      fclose(fp);fp = NULL;
   }

   return 0;
}

还创建函数来释放插入函数中分配的所有内存。