Видимо, массив уничтожился и указатель теперь ссылается на мусор.
Но при этом Если передать этот массив в OpenGL, вот так:
while (running)
{
...
double* m = createProjectionMatrix(fov, aspect, zNear, zFar);
glLoadMatrixd(m);
...
}
то всё работает. Сцена рендерится. Почему?
А если сделать нормально - выделить под массив память при помощи оператора new (ну или через функцию _malloca) и вернуть этот указатель. Тогда перебирается нормально. Но потом требуется уничтожить память оператором delete[].
Вопрос в том, почему без явного выделения памяти проиходит то, что происходит?
Потому что локальные переменные создаются в фрейме стека. И когда функция завершается, фрейм этой функции уничтожается (и массив внутри фрейма уничтожается тоже при выходе из функции).
Элементы массива тоже в этом случае размещаются (компилятором) в стеке, как будто бы была использована функция alloca
А тот указатель, который возвращает функция из OpenGL, он указывает на динамическую память (выделенную при помощи malloc). Динамическая память, она же “куча”, это не стек, и при выходе из функции с ней ничего не происходит.
Во втором примере, уничтожение массива не происходит, потому что переменная массива ещё не выходит из области видимости.
Это не понятно. Я же передаю туда указатель на переменную стека, которая, по-идее, уже уничтожена.
Второй пример это про OpenGL?’ Почему не выходит? Мы ведь уже вышли из функции createProjectionMatrix(), также как в первом примере вышли из create().
В чём разница?
Мы не видим текст функции createProjectionMatrix, и не знаем, как она выделяет память. Но может быть так, что данные на стеке не затираются. Случайно повезло.
Я же передаю туда указатель на переменную стека, которая, по-идее, уже уничтожена.
Ты вставь во втором примере между двумя вызовами ещё один. Вызови вспомогательную функцию, в которой выдели массив и перезапиши его содержимое. И тогда содержимое станет уничтожено не “по-идее”, а фактически.
Оптимизацию только надо в компиляторе подавить, чтобы не сработала и не удалила неиспользуемую переменную.