问题
Following this answer https://stackoverflow.com/a/29074955/1098041
I have a curious behavior.
In Debug I get the expected output, however in release (I'm using mingw on windows) I get garbage in the test
fonction.
#include <iostream>
#include <initializer_list>
template <class T>
struct array
{
T *ptr;
size_t len;
array() { clear(); }
array( T *p, size_t l ) { assign(p,l); }
inline void clear() { ptr=nullptr; len=0; }
inline void assign( T *p, size_t l ) { ptr=p; len=l; }
inline T& operator[] ( size_t i ) const { return ptr[i]; }
};
template <class T>
inline array<const T> wrap( std::initializer_list<T> lst )
{ return array<const T>( lst.begin(), lst.size() ); }
void test( int a, int b, int c )
{
auto ar = wrap({a,b,c});
std::cout<< ar[1] << std::endl;
}
int main()
{
auto a = wrap({1,2,3});
std::cout<< a[2] << std::endl;
test(1,2,3);
}
Output in debug :
3
3
Output in release:
3
2686868 // some garbage.
Can anyone explain to me how debug/release mode influences the lifetime of the initializer_list underlying array ? Or provide some other explanation for this behavior.
回答1:
auto a = wrap({1,2,3});
The lifetime of the initializer_list
(and its underlying array) ends at the end of that expression, so a
contains a dangling pointer.
That means std::cout<< a[2]
has undefined behaviour. Similarly for the code in test
, std::cout <<
a[1]` is also undefined behaviour.
Can anyone explain to me how debug/release mode influences the lifetime of the initializer_list underlying array ? Or provide some other explanation for this behavior.
It's undefined behaviour.
Anything can happen.
In release mode the compiler optimizes things differently, so the layout of variables on the stack is different, so code with undefined behaviour might do something different. Or it might not.
This isn't even specific to initializer_list
, you'd get similar undefined behaviour for any temporary object that you keep pointers into:
wrap( std::vector<int>(1, 1) );
来源:https://stackoverflow.com/questions/29077121/what-is-the-lifetime-of-the-array-underlying-a-stdinitializer-list