Reputation: 3
I'm having difficulty understanding what I'm doing wrong here. I'm making a program to organize a database of Books. I'm using a linked list to save the book structs to memory. When it comes to inputting the books information, I get
Segmentation fault (core dumped)
after inputting the first value, book identifier. In my AddBook function, I create a temp book struct (aBook). I then ask the user to input an identifier for the new book then attempt to save it to aBook's identifier attribute. This is where the error occurs.
Anyway, I included the top part of my program where I include libraries, declare functions etc, and I also included the menu function and addbook function so hopefully someone can spot what my mistake is. Thanks in advance.
Top Section of my code:
//Libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
//only 10 books maximum
#define MAX 10;
//function prototypes
void fileInput();
void menuSystem();
int writeAndCloseFile();
void addBook();
void takeOutBook();
void returnBook();
void deleteBook();
void viewAllBooks();
void viewBook();
void viewYearCollection();
int exitSystem();
bool isEmpty();
//The File
FILE *fp;
//LinkedList Initialization
struct bookData {
//book variables
char* identifier;
char* title;
char* author;
int year;
bool status;
char* customer;
int timesTakenOut;
char* genre;
};
//struct for one node
struct node {
struct bookData *element;
struct node *next;
};
//first and last nodes
struct node *firstBook = NULL;
struct node *lastBook = NULL;
Menu function and AddBook function (where error is occurring):
//MENU SYSTEM FUNCTION
void menuSystem()
{
int chosenOption = 0;
printf("****************\n\n");
printf(" MENU\n\n");
printf("****************\n\n");
printf("1 - Add book\n");
printf("2 - Take out book\n");
printf("3 - Return book\n");
printf("4 - Delete book\n");
printf("5 - View all books\n");
printf("6 - View book\n");
printf("7 - View Year Collection\n");
printf("8 - Exit\n\n");
printf("Chosen Option: ");
scanf("%d", &chosenOption);
//1. ADD BOOK
if(chosenOption == 1)
{
addBook();
}else if(chosenOption == 2){
//2. TAKE OUT A BOOK
takeOutBook();
}else if(chosenOption == 3){
//3. RETURN A BOOK
returnBook();
}else if(chosenOption == 4){
//4. DELETE A BOOK
deleteBook();
}else if(chosenOption == 5){
//5. VIEW ALL BOOKS
viewAllBooks();
}else if(chosenOption == 6){
//6. VIEW A BOOK
viewBook();
}else if(chosenOption == 7){
//7. VIEW YEAR COLLECTION
viewYearCollection();
}else if(chosenOption == 8){
//8. EXIT SYSTEM
printf("\n\nGoodbye!\n\n\n\n");
exitSystem();
}
}
void addBook(){
printf("\n*** ADDING BOOKS ***\n");
struct node *aBookNode;
struct bookData *aBook;
aBook = (struct bookData *)malloc(sizeof(struct bookData));
if (aBook == NULL)
printf("Error - no space for new book data\n\n\n");
else
{
//INPUT BOOK INFO
//Identifier
printf("\nIdentifier(####-####): ");
scanf("%9s", aBook->identifier);
fflush(stdin);
//Title
printf("Title: ");
scanf("%s", aBook->title);
The console output (After I inputted a random number for the identifier):
Could not open the file book.dat
****************** The database is empty. Books will need to be manually entered ******************
*** ADDING BOOKS ***
Identifier(####-####): 1234-1234
Segmentation fault (core dumped)
Upvotes: 0
Views: 188
Reputation: 41017
scanf("%9s", aBook->identifier);
You need to reserve space for aBook->identifier
and aBook->title
, an easy way is using strdup (is not part of the standard but it is available in many implementations):
char temp[10];
scanf("%9s", temp);
aBook->identifier = strdup(temp);
if (aBook->identifier == NULL) { /* Always check the return of strdup */
perror("strdup");
exit(EXIT_FAILURE);
}
Don't forget to call free(aBook->identifier);
at then end.
Upvotes: 2
Reputation: 409176
You allocate the bookData
structure, but you don't allocate memory for the strings inside the structure.
So when you ask scanf
to write to aBook->identifier
it will write to a seemingly random location and you end up with undefined behavior and the crash.
Either declare those members that are supposed to be strings as fixed-size arrays, or allocate memory for the strings.
Upvotes: 2