Reputation: 7719
This is my setup (boiled down). I have a "layout function":
struct LayoutFunc {
LayoutFunc( int limit , int value ) { lim.push_back(limit); val.push_back(value); }
//LayoutFunc(LayoutFunc&& func) : lim(func.lim),val(func.val) {}
LayoutFunc(const LayoutFunc& func) : lim(func.lim),val(func.val) {} // error: std::bad_alloc
LayoutFunc(const std::vector<int>& lim_,
const std::vector<int>& val_ ) : lim(lim_),val(val_) {}
LayoutFunc curry( int limit , int value ) const {
std::vector<int> rlim(lim);
std::vector<int> rval(val);
rlim.push_back(limit);
rval.push_back(value);
LayoutFunc ret(rlim,rval);
return ret;
};
std::vector<int> lim;
std::vector<int> val;
};
Then I have a class that uses LayoutFunc
:
template<class T> class A
{
public:
A( const LayoutFunc& lf_ ) : lf(lf_), member( lf.curry(1,0) ) {}
A(const A& a): lf(lf), member(a.function) {} // corresponds to line 183 in real code
private:
LayoutFunc lf;
T member;
};
The order of data members is correct. There are more types like class A
which use slightly different numbers to "curry" the layout function. I don't print them here to save space (they have the same structure, only different numbers). At the end I use something like:
A< B< C<int> > > a( LayoutFunc(1,0) );
which would build the "curried" layout function according to the template type order.
Now, probably this simple (boiled down) example works. However, in my real application at runtime I get a terminate called after throwing an instance of 'std::bad_alloc'
in the copy constructor of LayoutFunc
.
I think there is a flaw in the setup that has to do with taking a reference to a temporary and this temporary is destroyed before the consumer (in this case the copy constructor of LayoutFunc
) uses it. This would explain lim(func.lim),val(func.val)
to fail. But I can't see where the flaw is especially because curry
returns a true lvalue
. Also I tried it with the move constructor and compiled in c++11 mode. Same behaviour.
Here the backtrace:
#0 0x00007ffff6437445 in __GI_raise (sig=<optimised out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x00007ffff643abab in __GI_abort () at abort.c:91
#2 0x00007ffff6caa69d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff6ca8846 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff6ca8873 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff6ca896e in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff6c556a2 in std::__throw_bad_alloc() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00000000004089f6 in allocate (__n=18446744073709551592, this=0x7fffffffdaf8) at /usr/include/c++/4.6/ext/new_allocator.h:90
#8 _M_allocate (__n=18446744073709551592, this=0x7fffffffdaf8) at /usr/include/c++/4.6/bits/stl_vector.h:150
#9 _Vector_base (__a=..., __n=18446744073709551592, this=0x7fffffffdaf8) at /usr/include/c++/4.6/bits/stl_vector.h:123
#10 vector (__x=..., this=0x7fffffffdaf8) at /usr/include/c++/4.6/bits/stl_vector.h:279
#11 LayoutFunc (func=..., this=0x7fffffffdae0) at layoutfunc.h:17
#12 A (a=..., this=0x7fffffffdad0) at A.h:183
A.h:183 is the copy constructor of A
:
A(const A& a): lf(lf), member(a.function) {}
Upvotes: 2
Views: 5016
Reputation: 7719
A(const A& a): lf(lf), member(a.function) {}
should be
A(const A& a): lf(a.lf), member(a.function) {}
BЈовић comment pointed me in the direction to find this bug. if you post an answer, +1 BЈовић. Also +1 for sehe to make understand BT
Upvotes: 3