Зависит от вашего языка, но обычно массивы организованы в виде последовательности последовательных пробелов в памяти. Таким образом, вам не нужно хранить ячейки памяти для каждой точки в массиве, вы просто сохраняете одну ячейку памяти (начало массива), а затем добавляете смещение (смещение будет равным размеру каждой записи, умноженному на индекс Вы хотели), чтобы узнать, где конкретная запись находится в памяти.
Именно поэтому массивы обычно содержат только один тип, иначе вы не могли бы сделать такой простой расчет. Языки, которые позволяют хранить несколько типов, фактически создают обычный массив и размещают указатели на каждую запись в массиве - все указатели обычно имеют одинаковый размер. Этот уровень косвенности стоит, и поэтому «более простые» языки, как правило, медленнее.
В любом случае, когда вы выделяете больше памяти, вы хотите поместить новую память прямо в конец массива - в противном случае вы бы сегментировали свою память с дырой - зачем вам это делать?
То есть вы не можете просто расширить массив, не переместив его физически.
Компьютеры делают это годами, поэтому большинство языков имеют какой-то способ выделить новый фрагмент памяти, а затем сказать процессору, чтобы он блокировал копирование всех записей в новый блок и изменял указатель, чтобы отразить это, но часто (C, Java, ...) они оставляют это на усмотрение программистов с конкретными командами, чтобы скопировать массив, а не делать это за вас (возможно, просто чтобы сообщить вам, что расширение массива не является «свободным»
Можно было бы добавить указатель в конец массива, чтобы перейти к блоку новой памяти, который вы хотите добавить в конец массива, но теперь ваш поиск в массиве стал значительно медленнее .
Многие языки просто заключают массивы в коллекции, которые обеспечивают такую функциональность. Например, Java Vector / ArrayList автоматически перераспределяет память для вас. Связанный список фактически просто выделяет один элемент каждый раз с указателем на следующий. Добавляет элементы очень быстро, но очень медленно, чтобы перейти к элементу 5000 (вы должны читать каждый элемент, тогда как для элемента чтения массива 1 так же быстро, как элемент 5000)