Search code examples
c++arrayspointersstructuredynamic-memory-allocation

How to realloc an array of structs without a limit


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.


Solution

  • 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.