2

Having read literally dozens of answers here on the topic of lists, vectors, the new operator, RAII and this very good description of memory allocation, I still cannot imagine a practical implementation that meets the following need. Note I am most experienced in .net and its memory management, if that helps guide any answers.

Basically, I have class (say class RecordFile {}) that encapsulates a text file in a particular format. Each line equates to a record that I would like to add to a std::list<Record> owned by a RecordList instance, where the class Record captures the data from a single line in the file.

In the RecordList class, I have a method RecordList::Read() that reads the file line-by-line, creating a new Record instance and adding it to the list owned by the RecordList instance.

In this Read() method is a loop that iterates over the file's lines, creating the new Record instances. Clearly once the file is read and the Read() method finishes, I would like the list of records to persist in the RecordList object, but I cannot see how to do this without using the 'new' operator.

How is this task intended to be performed in c++ without violating what seem like fundamental rules? In .net this would be trivial and performed exactly as said without any risk to performance or memory leakage. I understand c++ is a different beast and am trying to get to grips with it.

Community
  • 1
  • 1
J Collins
  • 1,966
  • 22
  • 27

1 Answers1

4

The list container takes care of memory management for you.

Simply create a list member on your RecordList class like this:

std::list<Record> records_;

Then simply add lines using emplace_back:

records_.emplace_back(<whatever parameters `Record` constructor takes>);

When RecordList is destroyed, so is the list and all its elements.

imreal
  • 9,700
  • 2
  • 28
  • 45
  • That is quite cool, so elements are tightly owned by their container. Is that the entire intent for the emplace_* methods? Would this work the same way for a list where all elements belong to the same family of classes rather than just one concrete type? – J Collins Aug 15 '15 at 19:20
  • @JCollins The purpose of the emplace methods is to construct the object on site, as opposed to construct it somewhere else and then copy it into the container. And no, it wouldn't work on a family of objects, for that you would need smart pointers (`unique_ptr`/`shared_ptr`) which also handle lifetime for you. You can also create them and allocate memory for them without `new`, check the functions `make_unique`/`make_shared` – imreal Aug 15 '15 at 19:41
  • Thanks imreal, that looks like it is c++14, is that standard relatively universally adopted yet? – J Collins Aug 15 '15 at 19:56
  • 1
    @JCollins I think `make_unique` is C++14 (but it is on gcc 4.9), `make_shared` is C++11 which is very well adopted. You can initialize `unique_ptr` using `new` quite safely anyway. – imreal Aug 15 '15 at 20:08