Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there any issues with allocating memory within constructor initialization lists?

Tags:

I have used initialization lists a great deal in my C++ programs but wasn't aware that you could allocate memory within them.

So you can do something (as a contrived example) like this:

class Test { private:     int* i;     int* j;     int count;     int* k;  public:     Test(void) : i(new int), j(new int[10]), count(10), k(new int[count])     {     }      ~Test(void)     {         delete i;         delete [] j;         delete [] k;     } }; 

Are there any issues in doing memory allocation in this way? Regarding the order of initialization here is it safe to have a parameter initialized by one initialized in the same list? i.e. as I allocate count before I use it is it safe to use or is there some special initialization order I could fall foul of?

like image 999
Firedragon Avatar asked Jan 30 '12 13:01

Firedragon


People also ask

Does a constructor allocate memory?

A constructor does not allocate memory for the class object its this pointer refers to, but may allocate storage for more objects than its class object refers to. If memory allocation is required for objects, constructors can explicitly call the new operator.

Should my constructors use initialization lists or assignment?

Should my constructors use “initialization lists” or “assignment”? ¶ Δ Initialization lists. In fact, constructors should initialize as a rule all member objects in the initialization list.

What is the problem of initialization in constructor in C++?

Problem of initialization in C++ These data members have no explicitly defined scope thus they are private by default. The private data members cannot be initialized later using the object of the class. Here, if the data members are initialized using the object of the class, then it will show an error.

What is constructor initialization list?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.


2 Answers

It's not exception-safe. If the new for j throws an exception then the destructor for Test is not called, and so the memory for i is not freed.

The destructor of i is called if the initializer for j throws, it's just that a raw pointer has no destructor. So you could make it exception-safe by replacing i with a suitable smart pointer. In this case, unique_ptr<int> for i and unique_ptr<int[]> for j would do.

You can rely on the initializers to be executed in their correct order (the order the members are defined, not necessarily the order in the list). They can safely use data members that have already been initialized, so there's no problem with using count in the initializer for k.

like image 86
Steve Jessop Avatar answered Sep 18 '22 06:09

Steve Jessop


This code could leak memory in the presence of an initializer that throws an exception.

Note that this could be made to work correctly if the members of Test were smart -- rather than raw -- pointers.

like image 43
NPE Avatar answered Sep 22 '22 06:09

NPE