Search code examples
c++stldynamic-memory-allocationinitializer-list

Using "new" with initializer_list does not assign string values, while int values work


It works when I create a variable with std::initializer_list<std::string>:

auto a = std::initializer_list<std::string>{"1", "2", "3", "4"};

enter image description here

But when I create a variable with a pointer to std::initializer_list<std::string>, the values of the pointer are empty:

auto b = new std::initializer_list<std::string>{"1", "2", "3", "4"};

enter image description here

I tried with integer values and both cases work (std::initializer_list<int>{1, 2, 3, 4} and new std::initializer_list<int>{1, 2, 3, 4}).


Solution

  • In the standard (C++17) it says, referring to the array of const std::string which backs the initializer_list:

    The array has the same lifetime as any other temporary object, except that initializing an initializer-list object from the array extends the lifetime of the array exactly like binding a reference to a temporary.

    In your code the dynamically-allocated initializer-list object is initialized by the array, so this text applies.

    The lifetime extension rules for binding a reference to a temporary inside a new-initializer are: (C++17 [class.temporary]/6.3)

    A temporary bound to a reference in a new-initializer persists until the completion of the full-expression containing the new-initializer. [Example:

    struct S { int mi; const std::pair<int,int>& mp; };
    S a { 1, {2,3} };
    S* p = new S{ 1, {2,3} }; // Creates dangling reference
    

    So it seems the backing array is destroyed at the end of the line containing the new , so trying to inspect it after that would cause undefined behaviour (meaning you may or may not see what you expect).