Resource leak in Stroustrup example with std :: uninitialized_copy?

In the Struustrup book (C ++ 4th Edition Programming Language, Β§17.5.1, p. 508) I found the following copy constructor example for a simple Matrix class:

 template < class T > Matrix:: Matrix( const Matrix& m ) // copy constructor : dim{ m.dim }, elem{ new T[ m.size() ] } { uninitialized_copy( m.elem, m.elem+m.size(), elem ); // copy elements } 

(where elem is a pointer to an array of T elements declared as T* elem; ).

I have two questions about this copy constructor:

  • why does the first method create an array of m.size() elements by default, only to overwrite it in the body with uninitialized_copy ?

  • with initialization elem{ new T[ m.size() ] } , the constructor of T is called m.size() times. However, the uninitialized_copy algorithm in the body does not call the T destructor before building a new array in the same area. Is this a potential resource leak? (Note: no memory leak, resource leak, for example, if T receives a lock or file descriptor in ctor and frees it in dtor).

thanks

+8
c ++
source share
2 answers

Yes, this is clearly a mistake; the code should use copy instead of uninitialized_copy . Since T will usually be a trivial type, resource leaks are usually avoided, but it is still a mistake.

To answer your first question, it’s easier to write the initializer of the default instance constructor element by building an array, as this allows the copy constructor to use the same simple distribution method as the (n, m) constructor. It would be more efficient to allocate and embed an uninitialized region of memory, but this would complicate constructors and destructors that could be distracted from the point of the Matrix class. A more idiomatic way to write this would be with Matrix wrapping a dynamic array class (fixed size), for example dynarray (possibly message -C ++ 14 TS).

As Puppy pointed out, the copy constructor has a memory leak if its body throws away. This will happen whether copy or uninitialized_copy . Earlier, Straustrup said // simplified (no error handling) earlier in the class, so this can be excused.

I guess I would say how this error arose in the fact that Stroustrup uses uninitialized_copy elsewhere in the book, especially in its vector class. I do not have access to older versions, but I have a suspicion that this was added to replace the loop and try / catch block in the vector copy constructor, and the Matrix was modified similarly without full consideration.

It is not shown in Streustrup the list of errors for the 4th edition, but it may already know (the last page of corrections has been updated. November 2013). If you feel that you are sending it by email with this error, you should definitely do it!

+3
source share

I am the author of the question.
I asked two questions of Bjarne Stroustrup by email and decided to share my answers here.

He kindly (and briefly :-) answered:

  • This is supervision and waste.
  • Yes, if type T contains resources, this is a leak

He also wrote that he was going to fix the mistake.

+5
source share

All Articles