无法弄清楚为什么我在这个 C 程序中遇到分段错误(核心转储)

问题描述 投票:0回答:1

我似乎无法弄清楚为什么我在这个程序中遇到核心转储错误。包括初始化和读入动态结构数组的文件以及应将其读回的函数。

库.c 文件

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

#include "libraryStructures.h"
#include "library.h"
#include "user.h"
#include "librarian.h"
#include "utility.h"


void initLibrary(char *bookFile, Library *theLibrary)
{

  theLibrary->maxBooks = 100;
  theLibrary->maxBorrowed = 4;

  // TO DO :

  // dynamically allocate the bookList array for storing books
  Book *bookList = malloc(100 * sizeof *bookList);

  // check memory has been correctly allocated
  if ( bookList == NULL )
  {
    printf("\nOut of memory!\n");
    return;
  }  

  // open the book file
  FILE *books = fopen(bookFile, "r");


  // use the readBooks function to read in the file and add the book records into the bookList array
  readBooks(books, bookList);

  // remember to close the file
  fclose(books);
  // Initialise the User data

  return;
}


int readBooks(FILE *books, Book *bookList)
{

  // TO DO:

  /* read from the book file pointer
  assign values to a Book structure in the bookList array for each complete record */

  char buffer[50];
  int end = 0;
  int i = 0;
  int numOfBooks = 0;

  // while loop for reading book
  while(end != 1)
  {
    while(fgets(buffer,50,books)!=NULL)
    {
      numOfBooks = numOfBooks + 1;
      Book temp = bookList[numOfBooks];
      i = 1;

      for (int a = 0; a < 3; a++)
      {
        if (i == 1)
        {
          strcpy(temp.author, buffer);
          fgets(buffer,50,books);
          i = i + 1;
        }
        else if (i == 2)
        {
          strcpy(temp.title, buffer);
          fgets(buffer,50,books);
          i = i + 1;
        }
        else{
          temp.available = 1;
          bookList[numOfBooks] = temp;
        }
      }
    }

    end = 1;
  }
  // read data until the file ends
  for (int i = 0; i <= numOfBooks; i++){printf("here %s", bookList[i].title);}
  return numOfBooks;
}


void libraryCLI(char *bookFile)
{
  int libraryOpen = 1;
  int option;

  // create the library structure
  Library *theLibrary = (Library *)malloc(sizeof(Library));

  initLibrary(bookFile, theLibrary);

  while (libraryOpen)
  {
    printf("\n Main menu options\n 1 User login\n 2 Librarian login\n 3 Exit system\n Choice:");
    option = optionChoice();

    if (option == 1)
    {
      printf("\nUser login\n");
      userCLI(theLibrary);
    }
    else if (option == 2)
    {
      printf("\nLibrarian login\n");
      librarianCLI(theLibrary);
    }
    else if (option == 3)
    {
      libraryOpen = 0;
      printf("\nClosing\n");
    }
    else
      printf("\nUnknown option\n");
  }

  exitLibrary(theLibrary);

  // free the library structure
  free(theLibrary);

  return;
}

这部分程序就是出现故障的地方

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

#include "libraryStructures.h"
#include "librarian.h"
#include "utility.h"


void listBorrowedBooks(Book *bookList, int numBooks)
{
    // TO DO :
    // list the books in format "name - title"

    printf("%s\n", bookList[1].author); //THIS CAUSES FAULT

    return;
}

主要()

int main(int argc, char **argv)
{
    FILE * file;
    char *fileName = argv[1];
    char bookFile[40];

    // TO DO :
    // assign command line value to filename string
    if (argc <= 1)
    {
        fprintf(stderr, "Error: book file not chosen in command line.  Please enter a book file.\n\n");
        return 0;
    }
    else if(argc >= 3)
    {
        fprintf(stderr, "Error: too many arguments. Please enter one argument only.\n\n");
        return 0;
    }

    //checking if file exists and can be opened
    file = fopen(fileName, "r");
    if (file)
    {
        //check size of file
        fseek (file, 0, SEEK_END);
        int size = ftell(file);

        if (0 == size)
        {
            fprintf(stderr, "Error: file is empty. Please choose a file with content.\n\n");
            fclose(file);
            return 0;
        }
        else
        {
        // assign command line value to filename string
            strcpy(bookFile, argv[1]);
            fclose(file);
        }
    }

    else
    {
        fprintf(stderr, "Error: file does note exist or you do not have permission to open it. Please check the file exists and you have the correct permissions.\n\n");
        return 0;
    }

结构

typedef struct _book {

  char title[40];
  char author[40];
  int available;

} Book;


typedef struct _user {

  Book *borrowed[4];
  int numBorrowed;

} User;


typedef struct _library {

  Book *bookList;
  int numBooks;
  int maxBooks;

  User theUser;
  int maxBorrowed;

} Library;

编辑

更改了 readBooks() 函数,使其在循环结束时而不是开始时递增,并且缓冲区长度更改为 40

当我尝试打印时,listBorrowedBooks 函数中仍然出现分段错误

int readBooks(FILE *books, Book *bookList)
{

  // TO DO:

  /* read from the book file pointer
  assign values to a Book structure in the bookList array for each complete record */

  char buffer[40];
  int i = 0;
  int numOfBooks = 0;

  // while loop for reading book
  while(fgets(buffer,50,books)!=NULL)
    {
      Book temp = bookList[numOfBooks];
      i = 1;

      for (int a = 0; a < 3; a++)
      {
        if (i == 1)
        {
          strcpy(temp.author, buffer);
          fgets(buffer,50,books);
          i = i + 1;
        }
        else if (i == 2)
        {
          strcpy(temp.title, buffer);
          fgets(buffer,50,books);
          i = i + 1;
        }
        else{
          temp.available = 1;
          bookList[numOfBooks] = temp;
          numOfBooks++;
        }
      }
    }

  // read data until the file ends
  return numOfBooks;
}

这就是调用 listBorrowedBooks 的地方

void librarianCLI(Library *theLibrary)
{
    int librarianLoggedIn = 1;
    int option;

    while (librarianLoggedIn)
    {
        printf("\n Librarian options\n 1 List books\n 2 List borrowed books\n 3 Log out\n Choice:");
        option = optionChoice();

        if (option == 1)
        {
            printf("\nList of books:\n");
            listBooks(theLibrary->bookList, theLibrary->numBooks);
        }
        else if (option == 2)
        {
            printf("\nList of borrowed books:\n");
            listBorrowedBooks(theLibrary->bookList, theLibrary->numBooks);
        }
        else if (option == 3)
        {
            librarianLoggedIn = 0;
            printf("\nLogging out\n");
        }
        else
            printf("\nUnknown option\n");
    }
    return;
}

任何帮助表示赞赏!

c segmentation-fault coredump
1个回答
0
投票

问题(可能)是该语句的位置:

numOfBooks = numOfBooks + 1;

代码永远不会填充

bookList[ 0 ]
,但尝试从未初始化的结构中打印...

for (int i = 0; i <= numOfBooks; i++) {
    printf("here %s", bookList[i].title);
}

<=
循环中的
<
更改为
for()
。数组元素从
0
n-1
访问。

一旦加载完整记录,将增量从加载开始处移至后续:

        else{
          temp.available = 1;
          bookList[numOfBooks] = temp;
          numOfBooks++; // <-- increment count here
        }

编辑

void initLibrary(char *bookFile, Library *theLibrary)
{

  theLibrary->maxBooks = 100;
  theLibrary->maxBorrowed = 4;

  // TO DO :

  // dynamically allocate the bookList array for storing books
  Book *bookList = malloc(100 * sizeof *bookList); // LOCAL VARIABLE goes that out of scope.

bookList
是此函数的 local 变量。通过返回
void
,也许加载已经成功,但是当函数结束时,会出现内存泄漏,其余代码正在处理未初始化的数据。 在某个地方,你必须“嫁接”加载有指针的缓冲区,该指针的寿命比这个单个函数长。

© www.soinside.com 2019 - 2024. All rights reserved.