读取2kb txt文件时出现分段错误(c)

读取2kb txt文件时出现分段错误(c),c,file,segmentation-fault,fopen,C,File,Segmentation Fault,Fopen,下面是从文件中读取的代码,并将所述文件的每个字符串保存到二进制搜索树中。它适用于1KB的txt文件,但是当尝试使用更大的文件(2kb)时,我会遇到分段错误 #包括 #包括 #包括 #包括 类型定义结构listNode listNode; 结构列表节点{ int-id; ListNode*下一步; }; 类型定义结构树节点树节点; 树状结构{ 字符*字; 字符*键; 国际频率; ListNode*头; TreeNode*左; TreeNode*对; }; TreeNode*插入项(TreeNod

下面是从文件中读取的代码,并将所述文件的每个字符串保存到二进制搜索树中。它适用于1KB的txt文件,但是当尝试使用更大的文件(2kb)时,我会遇到分段错误

#包括
#包括
#包括
#包括
类型定义结构listNode listNode;
结构列表节点{
int-id;
ListNode*下一步;
};
类型定义结构树节点树节点;
树状结构{
字符*字;
字符*键;
国际频率;
ListNode*头;
TreeNode*左;
TreeNode*对;
};
TreeNode*插入项(TreeNode*根,字符*gword);
无效打印TreeInoder(TreeNode*v);
void searchforexist(树节点*根,字符*键);
#定义最大值25
int main()
{
字符字[MAX];
TreeNode*root=NULL;
文件*fp=fopen(“input.txt”,“r”);
如果(fp!=NULL)
{
while(fscanf(fp,“%s\n”,word)!=EOF)
{
root=插入项(root,word);
如果(strcmp(字,“eof”)==0)
打破
}
}
fclose(fp);
PrintTreeInoder(根);
printf(“\n”);
返回0;
}
TreeNode*插入项(TreeNode*根,字符*gword)
{
TreeNode*v=根;
TreeNode*pv=NULL;
while(v!=NULL)
{
pv=v;
int comp=strcmp(gword,v->word);
如果(补偿<0)v=v->左;
否则,如果(补偿>0)v=v->right;
其他的
{
char*key=v->word;
searchforexist(根,键);
返回根;
}
}
TreeNode*tmp=(TreeNode*)malloc(sizeof(TreeNode));
tmp->word=strdup(gword);
tmp->left=tmp->right=NULL;
tmp->freq=1;
if(root!=NULL)
{
如果(strcmp(gword,pv->word)<0)pv->left=tmp;
else pv->right=tmp;
}else根=tmp;
返回根;
}
void searchforexist(树节点*根,字符*键)
{
if(root==NULL | | root->key==key)
root->freq++;
如果(根->键<键)
searchforexist(根->右,键);
searchforexist(根->左,键);
} 
无效打印TreeInoder(TreeNode*v)
{
如果(v==NULL)返回;
printf(“(”);
PrintTreeInNorder(v->左);
printf(“)”;
printf(“%.4s”,v->word);
printf(“(”);
PrintTreeInoder(v->右);
printf(“)”;

}
一个简单的方法是使用gdb/lldb

我编译并调试了您的代码:

$ g++ -g -ggdb test.cc
$ lldb a.out
(lldb) r
Process 83386 launched: '/path/to/a.out' (x86_64)
Process 83386 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10)
    frame #0: 0x0000000100000ec1 a.out`searchforexist(root=0x0000000000000000, key="<link") at test.cc:104
   101  void searchforexist(TreeNode *root, char *key)
   102  {
   103     if (root == NULL || root->key == key)
-> 104         root->freq ++;
   105
   106
   107      if (root->key < key)
Target 0: (a.out) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10)
  * frame #0: 0x0000000100000ec1 a.out`searchforexist(root=0x0000000000000000, key="<link") at test.cc:104
    frame #1: 0x0000000100000eed a.out`searchforexist(root=0x0000000100102e50, key="<link") at test.cc:108
    frame #2: 0x0000000100000efe a.out`searchforexist(root=0x0000000100102b00, key="<link") at test.cc:111
    frame #3: 0x0000000100000d34 a.out`insertItem(root=0x0000000100102b00, gword="<link") at test.cc:78
    frame #4: 0x0000000100000c28 a.out`main at test.cc:47
(lldb)
$g++-g-ggdb test.cc
$lldb a.out
(lldb)r
已启动进程83386:“/path/to/a.out”(x86_64)
进程83386已停止
*线程#1,队列='com.apple.main thread',停止原因=EXC#U BAD#U访问(代码=1,地址=0x10)

帧#0:0x0000000100000ec1 a.out`searchforexist(根=0x0000000000000000,键=“在这里显示的内容之外,有很多机会使您的英雄程序出错。请在
scanf
格式中添加空格通常是个坏主意,因为这意味着函数必须一直读取,直到遇到非空格字符为止。
fscanf(fp,%s\n),word)!=EOF
如果文本的任何一行大于
MAX
,则可以越界写入,请使用
fgets
。还要注意
fclose
调用的位置。当前可以使用空指针调用它。请注意:我收到一个编译器警告C4717:“searchforexist”:在所有控制路径上递归,函数将导致运行时堆栈溢出问题在于,如果(ptr==NULL…),任何代码都不应该看起来像
ifptr->anything;
亲爱的@TimRandall,你说得对。这段代码有很多问题。在这种情况下,此段错误引发的直接问题是无法访问空指针。只想介绍一种方法来更轻松地调试代码,然后,我们可以在高层讨论其他问题
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct listNode {
  int id;
  struct listNode *next;
} ListNode;

typedef struct treeNode {
  char *word;
  char *key;
  int freq;
  ListNode *head;
  struct treeNode *left;
  struct treeNode *right;
} TreeNode;

TreeNode *insertItem(TreeNode *root, char *gword);
void printTreeInorder(TreeNode *v);
void searchforexist(TreeNode *root, char *key);
void freeNodes(TreeNode *root);

#define MAX 25
int main() {
  char word[MAX];
  TreeNode *root = NULL;

  FILE *fp = fopen("input.txt", "r");

  memset(word, 0, MAX);
  if (fp != NULL) {
    // why fsanf("%s \n") ? is this a very special format?
    while (fscanf(fp, "%24s \n", word) != EOF) {
      // fprintf(stderr, "got: [%s]\n", word);
      root = insertItem(root, word);

      if (strcmp(word, "eof") == 0) break;
    }

    fclose(fp);
  }

  printTreeInorder(root);
  printf("\n");

  freeNodes(root);
  return 0;
}

TreeNode *insertItem(TreeNode *root, char *gword) {
  TreeNode *v = root;
  TreeNode *pv = NULL;
  while (v != NULL) {
    pv = v;
    int comp = strcmp(gword, v->word);
    if (comp < 0) {
      v = v->left;
    } else if (comp > 0) {
      v = v->right;
    } else {
      // char *key = v->word;
      char *word = v->word;
      searchforexist(root, word);
      return root;
    }
  }

  TreeNode *tmp = (TreeNode *)malloc(sizeof(TreeNode));
  // why both key and word?
  tmp->word = strdup(gword);
  tmp->left = tmp->right = NULL;
  tmp->freq = 1;

  if (root != NULL) {
    if (strcmp(gword, pv->word) < 0) {
      pv->left = tmp;
    } else {
      pv->right = tmp;
    }
  } else
    root = tmp;

  return root;
}

void searchforexist(TreeNode *root, char *word) {
  if(root == NULL) {
    return;
  }

  int comp = strcmp(word, root->word);

  if(comp == 0) {
    root->freq++;
  } else {
    searchforexist(comp < 0 ? root->left : root->right , word);
  }

}

void printTreeInorder(TreeNode *v) {
    if (v==NULL) return;

    printf("(");
    printTreeInorder(v->left);
    printf(")");

    printf(" %.4s ", v->word);

    printf("(");
    printTreeInorder(v->right);
    printf(")");
}

void freeNodes(TreeNode *root) {
  if (root == NULL) {
    return;
  }
  freeNodes(root->left);
  freeNodes(root->right);

  if(root->word != NULL) free(root->word);
  if(root->key != NULL) free(root->key);
  free(root);
  return;
}