Составной литерал, объявленный внутри функции, имеет автоматическую продолжительность хранения, связанную с его вмещающим блоком (C 2018 6.5.2.5 5), что означает, что его время жизни заканчивается, когда заканчивается выполнение блока.
Внутри numbers
, *p = (int []){1, 2, 3};
присваивает адрес составного литерала *p
. Когда numbers
возвращается, составной литерал перестает существовать, и указатель недействителен. После этого поведение программы, использующей указатель, не определено. Программа может печатать значения, потому что данные все еще находятся в памяти, или программа может печатать другие значения, потому что память изменилась, или программа может перехватывать, потому что она пыталась получить доступ к недоступной памяти, или все поведение программы может измениться. радикально, потому что оптимизация компилятора полностью изменила неопределенное поведение во что-то еще.