Память под статический массив выделяется на стеке. При выходе из области видимости стек очищается и память под массивом освобождается автоматически (не нужна операция освобождения памяти, операция есть, но о ней позаботится компилятор самостоятельно).
Память для динамического массива выделяется в динамической памяти (в куче) (new[]). Когда массив становится не нужным память должна быть освобождена (delete[]), иначе произойдет утечка памяти.
В связи с вышеизложенными принципиальными отличиями, есть несколько следствий:
1. Имя статического массива это не указатель. Это можно понять например сравнив, что возвращает sizeoff() для статического массива и для динамического. Хотя в некоторых ситуациях компилятор ведет себя так, как будто имя статического массива это указатель, например: можно передать имя статического массива в функцию, принимающую указатель.
2. У динамического массива нет имени. Операция new[] возвращает указатель. Имя есть у указателя.
3. Внимание! Оба варианта массивов имеют фиксированный размер. Изменять его нельзя!
То что в std::vector вы можете укладывать кучу элементов постепенно, не указывая нигде предварительного размера является следствием того, что std::vector скрывает от вас всю работу, которую он при этом делает. При добавлении нового элемента, для которого нет места, он выделяет память для нового массива большего размера, копирует старый массив в новый, удаляет старый массив, добавляет новый элемент. Если идет интенсивная работа с push_back(), то это может ОООЧЕНЬ дорого стоить. std::vector - это удобно, но необходимо всегда помнить, за счет чего достигается это удобство. std::vector - это не динамический массив - это обертка над ним для более удобной работы с динамическим массивом.
В языке Си (C99) есть такая штука как Variable Length Array (VLA) - это статический массив с изменяемым размером. Т.е. вы можете, например, в функции объявить int arr[N], где N будет передаваться в функцию как параметр.
В стандарте С++ VLA нет! Но, например, тот же gcc с опциями по умолчанию разрешает его использования в С++ проектах. С опциями, заставляющими gcc более жестко следовать стандарту, он может запрещать использовать VLA в С++ проектах. Но не рассчитывайте, что все компиляторы будут так делать. Например микрософтовский компилятор в принципе не умеет в VLA (хотя я уже пару лет не проверял это).
VLA может показаться классной штукой.
Но, например, в ядре Линукс в свое время проводили целую компанию по выпиливанию VLA из исходников. Торвальдс высказывался негативно про VLA. Все это при желании можно нагуглить.
Стоит помнить, что размер стека ограничен, а VLA то же выделяется на стеке. Кроме того выделение памяти для обычного статического массива это просто увеличение счетчика стека на константу (и все, одна операция сложения регистра с константой, а компилятор одной операцией выделяет память для всех переменных в текущей области видимости). С VLA все сложнее с выделением и удалением. Так же sizeof() для обычного статического массива это операция времени компиляции (при выполнении будет уже заранее известная константа), для VLA - это полноценный вызов функции.