-1

So basically, I have an array of structs which I have dynamically allocated.

  using namespace std;
  struct library
  {
    string bookname;
    string author;
    int bookno;
  };
  int main()
  {
           library *lib=NULL;
           lib=malloc(sizeof(lib)*1);
           lib=(library*)realloc(lib,2);
           cout<<"Enter Book Name: "<<endl;
           getline(cin,lib[i]->bookname);
 }

In the above program I'm creating a array of structure for a library. I have reallocated from 1 space to 2 spaces which can be increased to more. But I'm having problem in getting input to member variable of each array member. The lib[i] is causing error here.

Holt
  • 36,600
  • 7
  • 92
  • 139
  • 4
    You can't create instances of a non-pod class with `malloc`, or arrays of them. Use `new`, or placement `new` on that storage. – François Andrieux Jan 18 '18 at 20:00
  • 5
    Or use a `std::vector`. – Holt Jan 18 '18 at 20:01
  • 7
    use `std::vector my_library;` – Richard Critten Jan 18 '18 at 20:01
  • 2
    `sizeof(lib)` is the same as `sizeof(library*)` and returns the size of the *pointer*. – Some programmer dude Jan 18 '18 at 20:01
  • @FrançoisAndrieux I don't know if that's a good duplicate. The accepted (and only) answer uses placement `new` instead of something more rational like `std::vector` or even regular `new`. – Blastfurnace Jan 18 '18 at 20:06
  • @Blastfurnace You can improve that question by providing a better answer. Even though the current answer is flawed, the questions are still very similar. – François Andrieux Jan 18 '18 at 20:14
  • You do the realloc right, but memory allocation do not create object (POD or not). You must use placement new as proposed in the link of François Andrieux. In c++ parlance `lib[i]->bookname` is an access to an object out of its lifetime period. The lifetime begin when the object is created by either its definition or a new expression. – Oliv Jan 18 '18 at 20:15
  • @FrançoisAndrieux The proposed duplicate is quite different in that it does not ask for a way to allocate a dynamic array of objects using `malloc` but a single object. To be a good duplicate, you would have to explain how you need to copy memory using `std::unitialized_copy` (maybe combined with a move iterator), when doing `realloc` + placement `new` on the remaining elements, which would not be an answer to the duplicate question. – Holt Jan 18 '18 at 20:17
  • 4
    `lib=malloc(sizeof(lib)*1);` -- This will not compile using C++, since the return value for `malloc` must be casted to a pointer of the type being assigned to. If you were using a `C` compiler, *then* this would compile without casting. Second, and I have to ask this -- where are you getting the idea to use `malloc`, `realloc`, and all of these `C`-ish things in a C++ program? If it's in a book, throw the book away -- if it's a teacher, get a new teacher. – PaulMcKenzie Jan 18 '18 at 20:18
  • @PaulMcKenzie This is a typo. corrections made – Oliv Jan 18 '18 at 20:26
  • @Oliv Unless you are working with OP, you don't know that for sure. It could well be that OP does not know how to use `malloc` with `sizeof`. – Holt Jan 18 '18 at 20:32
  • 2
    Why oh why would you be using C++, but still calling malloc? – smac89 Jan 18 '18 at 20:36
  • sorry about the code @PaulMcKenzie, I've been learning online and pdfs... I havent read enough of dynamic allocation and reallocation of structures using 'new' operator so I avoided using it. –  Jan 18 '18 at 20:44
  • 3
    For the love of $DEITY, just use `std::vector` already. – Jesper Juhl Jan 18 '18 at 20:47
  • 1
    @ArohanAjit That's not going to work well for you. You'll learn better and faster with [a good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Trust me. – Blastfurnace Jan 18 '18 at 20:53
  • @ArohanAjit -- *I havent read enough of dynamic allocation and reallocation of structures using 'new' operator so I avoided using it* -- Which probably means you are reading `C` material, not `C++` material, and decided to go with `C` routines. I know of no C++ tutorial, book, pdf, good or bad, that teaches you `malloc` and `realloc` as the dynamic allocation routines to use in a C++ program. – PaulMcKenzie Jan 18 '18 at 21:22
  • @ArohanAjit I have learn C++ with Stroustrup book (The C++ programming language) but "Programming principle and practice using C++" (second edition) may be more adequate if you have never programmed before. – Oliv Jan 18 '18 at 21:23

2 Answers2

1

Your struct library has std::string members, so isn't a "POD" (plain-old data) class. This means that simple C memory allocation isn't going to work, because the string constructors and destructors will not be called.

The easiest way of doing what you want to do is simply to use std::vector<library>. This will run the constructors and destructors correctly, and will resize itself automatically. If you want to, you can manually control the allocated size of the vector with reserve() and shrink_to_fit().

If you really, really must use malloc() and friends, then you will need to use placement new and a manual destructor call. Something like the following may work:

library *lib = nullptr;
lib = static_cast<library*>(malloc(sizeof(library)*2)); // note not sizeof(lib)
lib = new (lib) library[2]{}; // default construct an array of library at the given location
cout<<"Enter Book Name: "<<endl;
getline(cin,lib[0].bookname);
// ...do other library stuff...
lib[0].~library(); // destroy librarys
lib[1].~library();
free(lib); // deallocate storage

But note that you still can't use realloc(). You'll have to create a new array, invoke copy/move constructors with placement new, and then destroy and delete the original array.

Or just use std::vector, which does all this for you.

Tristan Brindle
  • 16,281
  • 4
  • 39
  • 82
0

From just looking at the code there are several things wrong

  1. you stated your problem is coming from: lib[i] Well, the code snippet provided never declares i
  2. lib is a pointer and when you use [] with a pointer you are referencing it meaning the -> will not work instead just use . like so: lib[i].bookname
  3. Tristan Brindle is correct you need to use new
nkr
  • 3,026
  • 7
  • 31
  • 39
  • Actually I declared the i earlier in the program, I just added the necessary part because it was tedious copying everything for ubuntu. But thanks for the advising . instead of -> thing. It worked! –  Jan 18 '18 at 20:42