【问题标题】:Infinite Loop /Segmentation error无限循环/分段错误
【发布时间】:2016-09-16 02:57:12
【问题描述】:

得到一个无限循环,但是当我尝试“//”两个循环时,我开始收到 fseek() seg 错误...

文件目的...:查找文件之间的常用短语(词组)。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define CONTENTS 20000
#define MAXFILES 30
#include "hash.h"


void printOutput(int numFiles, int output[30][30])
{
  int i, j;
 //print output matrix
 for (i = 0; i < numFiles; i++){
    printf("f%d    ", i + 1); // print upper row of file names, use 4 spaces
 }

 for (i = 0; i < numFiles; i++){
    if (i > 8) // if file marker is 2 digits, use 2 spaces
    {
        printf("f%d  ", i + 1); // print upper row of file names
    }
  else printf("f%d   ", i + 1); // else file marker is 1 digit, use 3 spaces

  printf("\n");
    for (j = 0; j < numFiles; j++){
        // the following if else statements manage the spacing for various numbers, soley for aesthetic purposes
        if (output[i][j] == 45){ // print the dash character
            printf("%c     ", output[i][j]); // use 5 spaces
            continue;
        }
        else if (output[i][j] > 9 && output[i][j] < 100){ // if 2 digit number, 4 spaces
            printf("%d    ", output[i][j]);
            continue;
        }
        else if (output[i][j] > 99 && output[i][j] < 1000){ // if 3 digit number, 3 spaces
            printf("%d   ", output[i][j]);
            continue;
        }

        else if (output[i][j] > 999 && output[i][j] < 10000){ // if 4 digit number, 2 spaces
            printf("%d  ", output[i][j]);
            continue;
        }
        else if (output[i][j] > 9999){ // if 5 digit number, 1 space
            printf("%d ", output[i][j]);
            continue;
        }
        else printf("%d     ", output[i][j]); // 1 digit number, 5 spaces
    }
    printf("\n");
}
}


 int main(int argc, char *argv[])
{
  int group_length, valid;
  int list[30];
  //Range checking
  while( valid == 0 ) 
 {
    printf("What is the number of words to analyze (2 - 10)?\n");
    scanf("%d",&group_length);

    if( (group_length < 2) || (group_length > 10) )
       printf("\n");
    else
        valid = 1;
   }

  struct node * Map[30];
  int f;
  for(f = 0; f < 30; f++)
  {
     Map[f] = createHash(2000);
  }

  FILE *fp;
  int i, numberF = 0;
  int output[30][30]; // upper triangular output matrix
  char name[CONTENTS];
  char fnames[CONTENTS];
  fp = fopen("inputfile.txt", "r");
  char *names = malloc(sizeof *names);
  int *SequenceList = malloc(sizeof *SequenceList);
  //int *SequenceList  malloc(MAXFILES * sizeof(int *));
  int seq; //Sequence
 char entireFile[CONTENTS];
 char *wordArray[CONTENTS];
 char *token2, *search = " \r\n\t";

 for (i = 0; fgets(name, 100, fp) != NULL && i < MAXFILES; i++) 
 {
    ++numberF;
    char *token = NULL; //setting to nukl before using it to strtok
    token = strtok(name, ":");
    strtok(token, "\n");//Getting rid of that dirty \n that I hate
    strcat(&fnames[i], token);
    //Part 2:
    FILE *fpp;
    fpp = fopen(fnames,"r");
    fseek(fpp, 0, SEEK_END);
    int inputLength = ftell(fpp);
    rewind(fpp);
    //Reads data from a given stream into an array pointed to
    fread(entireFile, inputLength, 1, fpp);
    fclose(fpp); 
   //Closing file
   token2 = strtok(entireFile, search); 
   seq = 0;
   //wordArray[seq] = token2;
   char temp[CONTENTS];

   while (token2 != NULL)
   {
      while(seq < group_length)
     {
         token2 = strtok(NULL, search);
         wordArray[seq] = token2;
         strcpy(temp, wordArray[seq]);
         insertHash(Map[i], temp, SequenceList[i]);
         seq++;
         //output[i] = Map[i]->counts[i];
     }
    }//End of token2 NULL loop

   } 

    //closing  inputfile.txt... Presuming now is best time
   fclose(fp);

   //Printing and calling printOutput function
   int k, l;
  for (k = 0; k < 30; k++)
      for (l = 0; l < 30; l++)
         output[k][l] = 45;       
  printOutput(numberF, output);

return 0;

}

我在说什么的片段......:

FILE *fpp;
  fpp = fopen(fnames,"r");
  fseek(fpp, 0, SEEK_END);
   int inputLength = ftell(fpp);
  rewind(fpp);
  //Reads data from a given stream into an array pointed to
   fread(entireFile, inputLength, 1, fpp);
   fclose(fpp); 
  //Closing file
  token2 = strtok(entireFile, search); 
   seq = 0;
   //wordArray[seq] = token2;
  char temp[CONTENTS];

  while (token2 != NULL)
  {
     while(seq < group_length)
    {
        token2 = strtok(NULL, search);
          wordArray[seq] = token2;
        strcpy(temp, wordArray[seq]);
        insertHash(Map[i], temp, SequenceList[i]);
        seq++;
        //output[i] = Map[i]->counts[i];
     }
    }//End of token2 NULL lo

我的 hash.c 代码(确保它永不过期并且是公开的):http://pastebin.com/Cz4R7WwK //已更新 它的标题:http://pastebin.com/ex2zARGt

编辑: 最新添加后出现新的段错误.. 在 hash.c 中我的 insertHash 的 cmp 部分出现 seg 错误 这是insertHash中的警告

scratch_Hash.c: In function ‘insertHash’:
scratch_Hash.c:47:4: warning: passing argument 1 of ‘hash’ discards ‘const’ qual    ifier from pointer target type [enabled by default]
ha = hash(info)%200;
^
 scratch_Hash.c:31:15: note: expected ‘unsigned char *’ but argument is of type      const char *’
 unsigned long hash(unsigned char *str)
                      ^
 scratch_Hash.c:57:12: warning: assignment from incompatible pointer type [enable    d by default]
   node = node->next;
        ^
 scratch_Hash.c:64:18: warning: assignment from incompatible pointer type [enable    d by default]
newNode->next = table[ha];

前两个我可以稍后再做,但担心指针类型不兼容。在这种情况下我该如何解决?

seg 错误所在的直接点...:

  while(node != NULL)
  {
    if (strcmp(node->data,info) == 0)
    {    
      node->counts[file]++;  
      return node;  
    }
   node = node->next;
}

【问题讨论】:

  • 在编译时添加警告会对您有所帮助
  • 一旦 seq == group_length 外部 while 循环永远运行。为什么会在那里?

标签: c file hashtable phrase


【解决方案1】:

分配存在一些问题。在您的struct node 定义中,您有

int   counts[30];

但是当您 createHash(2000) 时,您访问的次数最多为 counts[1999]。您可能打算让 counts 像

这样的指针
int *counts;

并在createHash中分配

newTable->counts = malloc(size * sizeof(int));

此外,您在堆上的分配只是为指针分配了足够的内存,而不是结构本身。例如在 hash.c

struct node * newTable = malloc(sizeof *newTable);

将为指针分配足够的内存,而不是为struct node。您可能想改用

struct node * newTable = malloc(sizeof(struct node));

对于无限循环问题,insertHash 的第一个参数是 struct node** 类型,但您传递的是 struct node*。你想用

insertHash(Map, ...

编译器警告应该指出这些问题。最后,在您的 node 定义中,您定义

struct Node *next;

但你想要

struct node *next;

【讨论】:

  • 是的,我可能应该让它大小为 30...因为我真的只需要 30。我不小心将多少个字符数而不是最大文件数用于创建用于计数的 createHash。所以我将在 int counts[30] 处离开。谢谢你。很抱歉,像 struct node *next 这样的愚蠢错误。没抓到。并且使用 insertHash(map...) 而不是 insertHash(map[i],...) 似乎摆脱了那个警告,但是我如何编写它仍然可以通过这种方式得到我想要的吗?当我在 createHash struct node * newTable = maloc(sizeof(node));我收到一条错误消息,提示未声明节点
  • 修复:struct node * newTable = malloc(sizeof(struct node));
  • 也用缺失的结构更新了答案。您需要进行其他更改才能使 insertHash(Map,... 工作,例如传递 i。您还可以将函数声明更改为 insertHash(struct node* node,...) ,它将处理调用 insertHash(Map[i ],...)
  • 如果我把它改成 insertHash(struct node* **table, ...) 那么我就不用担心传递 i 了吗?
  • 是(更改为 struct node *table)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
相关资源
最近更新 更多