Re: crash in test suite testKernelInterpolation2D with STLPort : the iterator shouldn't be stored?

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: crash in test suite testKernelInterpolation2D with STLPort : the iterator shouldn't be stored?

Luigi Ballabio
Hi Marcello,
    you're right, the test as it's written might invalidate iterators
(the reason Dirkumware's version works, I think, is that in their
implementation v.clear() doesn't actually free the memory and
assigning new values reuses it as long as its capacity is enough).
I've committed to the Subversion trunk a version of the test that
doesn't invalidate the stored iterators; let me know if it works with
STLPort.

As for interpolators, storing iterators is indeed dangerous, but we
wanted to prevent having to copy the data (also, we did want to be
able to change a vector element, call update() and have the
interpolation work).  For the time being, classes which store an
interpolation instance recreate it when the underlying iterators
change.  Your idea of passing the new iterators might be an
alternative (maybe an overload of update() taking the new ones?)

Later,
    Luigi


On Tue, Nov 20, 2012 at 6:43 PM, marcelloptr
<[hidden email]> wrote:

>
> Using QuantLib-1.2.1 with STLPort-5.2.1, compiled under vs2010. Win32.
>
> The test suite run all tests perfectly but one:
>
> 1>  unknown location(0): fatal error in
> "QuantLib::detail::quantlib_test_case(&InterpolationTest::testKernelInterpolation2D)":
> std::runtime_error:
>       1>D:\Projecs\STLport-5.2.1\stlport\stl/debug/_debug.c(575): STL error
> : Uninitialized or invalidated (by mutating operation) iterator used
>
> The reason goes deep in the C++ specifications of a copy of an iterator, and
> probably the use of it in InterpolationTest::testKernelInterpolation2D is
> incorrect. MS's Dirkumware library probably doesn't crash because it doesn't
> perform the debug check that STLPort is capable of.
>
> Here's what happens:
>
> void InterpolationTest::testKernelInterpolation2D()
> {
>     ... // some test code
>
>     KernelInterpolation2D kernel2DEp(xVec1.begin(),xVec1.end(),
>                                      yVec1.begin(),yVec1.end(),M1,
>                                      &epanechnikovKernel);
>
>     ... // some test code
>
>     // test updating mechanism by changing initial variables
>     xVec1.clear();yVec1.clear(); // invalidates iterators of kernel2DEp too
>
>     xVec1+=60.0,95.0,105.0,135.0;
>     yVec1+=12.5,13.7,15.0,19.0,26.5,27.5,29.2,36.5;
>
>     kernel2DEp.update(); // <-- crash here.
>
>    ... // some test code
> }
>
> KernelInterpolation2D stores the iterators: begin() and end() of xVec1 and
> yVec1.begin()
> in the variables: xBegin_, xEnd_, yBegin_ and yEnd_ of kernel2DEp,
> then update() is called from within the KernelInterpolation2D ctor.
>
> Later the iterators of xVec1 and yVec1 are invalidated
> xVec1.clear();yVec1.clear();
>
> and this invalidates also the iterators in kernel2DEp because it stored
> them.
>
> When doing
>    xVec1+=60.0,95.0,105.0,135.0;
>     yVec1+=12.5,13.7,15.0,19.0,26.5,27.5,29.2,36.5;
> we have again a valid begin() iterator for xVec1 and yVec1, but they are not
> the ones that have been copied into kernel2DEp. (KernelInterpolation2D
> keeps a copy of them, not a reference)
>
> This seems logically correct to me, because reinitializing the data in a
> vector usually requires the allocation of a different memory area, and so
> the previous copied iterator should be invalid or at least not guaranteed to
> be valid.
>
> When later we run kernel2DEp.update(); we have of course the crash.
>
>
> The final answer can be given only by someone who knows well the C++ STL
> specifications on this, I guess, but I highly doubt that STLPort is wrong on
> this.
>
>
> Some considerations:
> My overall impression is that the idea of storing those iterators that are
> used to initialize KernelInterpolation2D is dangerous.
> What about passing them as argument every time is needed instead?
> Is it necessary to store them? If it is necessary then maybe the function
> update() that is using them should be made protected: not public:.
> I didn't look enough into your (excellent) library to tell.
>
> With Interpolation2D::update() protected the following files wouldn't
> compile:
> extendedblackvariancesurface.cpp(83)
> capfloortermvolsurface.cpp(225)
> flatextrapolation2d.hpp(76)
>
> If you want to store those pointer and keep update() public, then maybe a
> public setter for those iterators could be provided and the test made
> working.
>
> No matter what, to find a way to avoid this problem to the user or a way to
> check against this incorrect use would be welcome because only STLPort debug
> seems to warn you against this.
>
>
>
> --
> View this message in context: http://old.nabble.com/crash-in-test-suite-testKernelInterpolation2D-with-STLPort-%3A-the-iterator-shouldn%27t-be-stored--tp34702882p34702882.html
> Sent from the quantlib-users mailing list archive at Nabble.com.
>
>
> ------------------------------------------------------------------------------
> Monitor your physical, virtual and cloud infrastructure from a single
> web console. Get in-depth insight into apps, servers, databases, vmware,
> SAP, cloud infrastructure, etc. Download 30-day Free Trial.
> Pricing starts from $795 for 25 servers or applications!
> http://p.sf.net/sfu/zoho_dev2dev_nov
> _______________________________________________
> QuantLib-users mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/quantlib-users

------------------------------------------------------------------------------
Keep yourself connected to Go Parallel:
TUNE You got it built. Now make it sing. Tune shows you how.
http://goparallel.sourceforge.net
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users