Initializer list of variables

后端 未结 1 1905
猫巷女王i
猫巷女王i 2021-01-24 07:44

Is it possible to create an initializer_list of variables, like function arguments for example (cf. function test)?

The code below works, and n

1条回答
  •  再見小時候
    2021-01-24 08:16

     auto ar = wrap({a,b,c}); 
    

    This create a temporary array of type int[3], then binds an initializer_list to that array, then calls wrap which creates an array that refers to the array.

    At the end of the expression the array is destroyed, leaving the array with a dangling pointer, so this is undefined behaviour:

     std::cout<< ar[2] << std::endl;
    

    This also applies to the code in main, the variable a contains a dangling pointer and a[2] is undefined behaviour.

    You can verify this by replacing the array of int with an array of types that allocate memory, so that valgrind or asan will notice the bug:

    using V = std::vector;
    auto a = wrap({V{1}, V{2}, V{3}});
    std::cout<< a[2].front() << std::endl;
    

    Now a[2] is a std::vector object, but trying to access its front() member causes the program to abort:

    ==28356==ERROR: AddressSanitizer: heap-use-after-free on address 0x60200000efb0 at pc 0x000000401205 bp 0x7fffa46f2900 sp 0x7fffa46f28f8
    READ of size 4 at 0x60200000efb0 thread T0
        #0 0x401204 in main /tmp/il.cc:28
        #1 0x3236e21d64 in __libc_start_main (/lib64/libc.so.6+0x3236e21d64)
        #2 0x400ec8  (/tmp/a.out+0x400ec8)
    ...
    

    Or with valgrind:

    ==28364== Invalid read of size 4
    ==28364==    at 0x400C72: main (il.cc:28)
    ==28364==  Address 0x51dfd20 is 0 bytes inside a block of size 4 free'd
    ==28364==    at 0x4A07991: operator delete(void*) (vg_replace_malloc.c:502)
    ==28364==    by 0x4013BF: __gnu_cxx::new_allocator::deallocate(int*, unsigned long) (new_allocator.h:110)
    ==28364==    by 0x4012F8: std::allocator_traits >::deallocate(std::allocator&, int*, unsigned long) (alloc_traits.h:386)
    ==28364==    by 0x4011B1: std::_Vector_base >::_M_deallocate(int*, unsigned long) (stl_vector.h:178)
    ==28364==    by 0x40102A: std::_Vector_base >::~_Vector_base() (stl_vector.h:160)
    ==28364==    by 0x400EC4: std::vector >::~vector() (stl_vector.h:425)
    ==28364==    by 0x400C2A: main (il.cc:27)
    

    Side question; if I tried to return my wrapped array in test, the initializer list {a,b,c} would get out of scope, and the array I'm returning would be invalid -- is that correct?

    It's already out of scope and ar already invalid even before you return it.

    0 讨论(0)
提交回复
热议问题