1

I have a class named book, that contains books.

#ifndef BOOK_H
#include<string>
#include<vector>
#include<iostream>
#define BOOK_H
class book
{
public:
    std::string Author, Title;
    int Year;
    book(){}
    book(std::string author, std::string title, int year);
    ~book(){}
    void add_book();
    std::vector<book*>library;
};  
#endif

book.cpp file

#include "book.h"

book::book(std::string author, std::string title, int year)
:Author(author), Title(title), Year(year){} 

void book::add_book()
{
    int y;
    std::string a, t;
    std::cin>>a;
    std::cin>>t;
    std::cin>>y;
    library.push_back(new book(a, t, y));
}

But when I want to add a new book to the library, I'm getting a segmentation fault during the push_back of the new object in main.cpp file

#include "book.h"

int main()
{
    book* ptr;
    ptr->add_book();
    return 0;
}

Could someone explain to me what the problem is?

I'm new in OOP, and though I've read a lot of posts here I still can't find a solution.

3
  • 1
    The whole idea of having a separate library for each book looks a bit faulty to me. Also you declare book* but never initialize it and then call one of its methods. Commented Apr 25, 2016 at 9:31
  • FYI: class names are usually written in title case. This makes it easier for someone else to understand your code. Commented Apr 25, 2016 at 9:42
  • @OnMyLittleDuck: Class names are usually written in whatever style the class author follows, and I know plenty of programmers that follow styles that don't use title case. Commented Apr 25, 2016 at 10:33

3 Answers 3

2

You don't initialise the ptr in main;

int main()
{
    book* ptr = new book(); // initialize it here
    ptr->add_book();
    return 0;
}

This will fix the segfault, however, I'm not sure of the logic associated with the sample code, and possible memory leaks.


I would look to separate the library from the book type for better composition and avoid the heap allocation;

#include<string>
#include<vector>
#include<iostream>

class book
{
public:
    std::string Author, Title;
    int Year;
    book(){}
    book(std::string author, std::string title, int year) : Author(author), Title(title), Year(year) {} 
    ~book(){}
};  

struct library {
    std::vector<book> books_;
    void add_book(const book& value) { books_.push_back(value); }
};

int main()
{
    library lib;
    int y;
    std::string a, t;
    std::cin>>a;
    std::cin>>t;
    std::cin>>y;
    lib.add_book(book(a, t, y));
    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

2

Well, here:

book* ptr;
ptr->add_book();

ptr is unassigned, so its use causes seg fault. You should assign it before use:

ptr = new book();

this will cause memory leak so I suggest (if you like dynamic allocation):

auto ptr = std::make_unique<book>();
ptr->add_book();

but, why you need pointer anyway, this:

book bk;
bk.add_book();

will work the same way.


On the other hand, why your bookclass keeps a vector of book instances? You need a library class which will keep a vector of book-s.

1 Comment

Thanks for explanation. I will remember about that, unfortunately I'm working at c++11 compiler right now. Can't answer this question now. I must practice more :) But thanks again for idea of creating second class.
1

You will have to make an object of class Book before using its methods.

Book *ptr = new Book();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.