Saul Teukolsky
10-13-2002, 06:16 PM
David Wilkinson has written the following note. We'd be interested to hear other readers opinions.
Dear NR:
I am using version 2.10 of Numerical Recipes in C++.
Some of your utility classes, in particular NRMat, are not exception
safe, in the sense that they can leak memory when an exception occurs.
Any class whose constructor contains more than one "new" operation will
leak memory if any allocation beyond the first fails (because the
destructor of the class being constructed does not run in this case).
The correct way to deal with this issue is to use the "resource
allocation is initialization" methodology described in Stroustrup's
book. For the case of NRMat I think it can be achieved by making the
member variable v a NRVec<T*> rather than a T**. Note that the current
implementation is more likely to fail on the second allocation than the
first, because the second allocation is bigger.
More generally, I do not find any discussion of exceptions in the book.
The C++ standard requires that "new" throws std::bad_alloc when it
fails. Since the NR codes (e.g. the NRMat constructor) do not check for
NULL returns from "new", they would appear to be expecting
std::bad_alloc to be thrown. However some common compilers, notably VC5
and VC6, do not implement this behavior (they return NULL from a failed allocation).
This is a (BIG) Microsoft problem, not a Numerical Recipes
problem, but I think some discussion of it would have been in order.
Sincerely,
David J. Wilkinson
President, Efficient Solutions Inc.
Dear NR:
I am using version 2.10 of Numerical Recipes in C++.
Some of your utility classes, in particular NRMat, are not exception
safe, in the sense that they can leak memory when an exception occurs.
Any class whose constructor contains more than one "new" operation will
leak memory if any allocation beyond the first fails (because the
destructor of the class being constructed does not run in this case).
The correct way to deal with this issue is to use the "resource
allocation is initialization" methodology described in Stroustrup's
book. For the case of NRMat I think it can be achieved by making the
member variable v a NRVec<T*> rather than a T**. Note that the current
implementation is more likely to fail on the second allocation than the
first, because the second allocation is bigger.
More generally, I do not find any discussion of exceptions in the book.
The C++ standard requires that "new" throws std::bad_alloc when it
fails. Since the NR codes (e.g. the NRMat constructor) do not check for
NULL returns from "new", they would appear to be expecting
std::bad_alloc to be thrown. However some common compilers, notably VC5
and VC6, do not implement this behavior (they return NULL from a failed allocation).
This is a (BIG) Microsoft problem, not a Numerical Recipes
problem, but I think some discussion of it would have been in order.
Sincerely,
David J. Wilkinson
President, Efficient Solutions Inc.