Правильно понимаю суть?
1) Статические массив может содержать элементы только одного типа, потому что в нем вот такая штука. Например адрес начальной ячейки памяти - 1000. Под массив отводится заданное количество слотов идущих подряд друг за другом и имеющих заданный размер в байтах. Например 4 байта, если это тип int. И таким образом адрес ячейки i получаем по формуле
ar(начало массива) + ( i - 1) * k(размер ячейки в байтах).
Поэтому тип в массиве и должен быть один и тот же. У int размер 4 байта, у char - 1 байт. Так?
2) В динамический массив можно помещать данные разных типов потому что в них хранятся не сами данные, а ссылки на эти данные в других местах памяти.
И сами динамические массивы построены на статических, но действуют так - когда происходит переполнение массива создается новый массив вдвое большей длины с пустыми слотами, в его первую половину копируются на данные из старого массива и старый массив удаляется из памяти. Верно?
C/C++
надо смотреть что получается на выходе. на этом сайте например я увидел, что
1) при изменении числа в return слева, справа оно увеличивает число на 4 в инструкции [rbp+...]
2) создаются инструкции DWORD PTR, то есть кажется хранятся 32-битные значения под каждое число. при переполнении массива создалась только ассемблерная запись на 8 строчке
Устройство статических и динамических массивов в оперативной памяти (...)
Ты путаешь тёплое с мягким.
Есть выделение памяти под сам массив, а есть подход к выделению памяти под его элементы.
Сам массив (по способу выделения памяти) может быть:
Совершенно независимо от способа выделения памяти под массив, элементы массива могут:
А также можно выделить память под массив без инициализации элементов и инициализировать их вручную:
Массив 'a' может быть выделен любыми средствами: через Сишный malloc, через отображаемый файл и т.д.
Есть выделение памяти под сам массив, а есть подход к выделению памяти под его элементы.
Сам массив (по способу выделения памяти) может быть:
- Статическим (память выделяется при компиляции).
int a[100500]; // в глобальной области видимости
static int a[100500]; // в классе или функции
- Динамическим (память выделяется во время выполнения и должна освобождаться симметричным вызовом delete).
int *a = new int[100500];
// обрабатываем, обрабатываем
delete a; // освобождаем память
- Автоматическим (память выделяется в стеке).
int a[100500]; // в функции
- Отображённым на готовый участок памяти (например, на memory-mapped file или на другую структуру данных со своей аллокацией).
int *a = (int*)&myStruct;
int *a = (int*)mmap(NULL, length, PROT_READ,
MAP_PRIVATE, fd, pa_offset);
Совершенно независимо от способа выделения памяти под массив, элементы массива могут:
- Лежать в самом массиве и инициализироваться при выделении памяти под массив:
MyClass a[100500]; // все 100500 элементов будут последовательно инициализированы,
// и для них вызваны конструкторы,
// при выделении памяти под массив
- Быть указателями на конечный тип и инициализироваться по необходимости:
MyClass *a[100500];
for (size_t i = 0; i < 100500; i++) {
a[i] = new MyClass(params);
}
// обрабатываем, обрабатываем
for (size_t i = 0; i < 100500; i++) {
delete a[i];
}
// 'a' выделен в стеке, поэтому его освобождать не надо
А также можно выделить память под массив без инициализации элементов и инициализировать их вручную:
MyClass *a = (MyClass*)new char[100500 * sizeof(MyClass)];
new(a) MyClass(params1);
new(a + 1) MyClass(params2);
// ...
new(a + 100499) MyClass(params100500);
Здесь элементы массива имеют конечный тип (не указатель) и даже могут быть разных типов, но на этот случай программист должен вручную выделить достаточный объём памяти под все экземпляры. Вызовы new(ptr) для элементов не выделяют память, а работают на уже выделенном участке памяти, и указатели на отдельные элементы освобождать не надо. Освобождать надо только память, выделенную под массив 'a'. Но деструкторы для таких элементов придётся вызывать вручную: a[0].~MyClass();
a[1].~MyClass();
// ...
a[100499].~MyClass();
и только потом освобождать память самого массива: delete (void*)a;
(приведение к void нужно, чтобы компилятор не взялся вызывать деструктор от a[0])Массив 'a' может быть выделен любыми средствами: через Сишный malloc, через отображаемый файл и т.д.
У всех массивов (не путать с классами и структурами) все элементы должны быть одного типа. Статический, динамический и автоматический - только способы выделения памяти (статический - на этапе компиляции, динамический - в "куче" по запросу на этапе выполнения, автоматический - на стеке во время вызова функции). При переполнении любого массива происходит разрушение памяти (запись в ячейки, не предназначенные для записи данных этого массива).
Есть еще классы хранения данных (контейнеры): вектор, очередь, список и т.п., вот там программно может быть реализована любая логика выделения памяти и хранения данных.
Есть еще классы хранения данных (контейнеры): вектор, очередь, список и т.п., вот там программно может быть реализована любая логика выделения памяти и хранения данных.
1. Любой массив подчиняется первому утверждению.
2. Это частный случай массива где в качестве элемента ссылка или указатель. В вашем примере это не определяет тип, так как вы можете все это сделать даже в статической памяти. И не следует путать массивы с контейнерами.
Единственное что отделяет динамический тип - где в итоге он будет расположен.
В программе, но вне любой из функций - статический (в статической области памяти)
В одной из функций (в т.ч. main) - автоматический (обычно в стеке)
Вне программы - динамический (в куче)
2. Это частный случай массива где в качестве элемента ссылка или указатель. В вашем примере это не определяет тип, так как вы можете все это сделать даже в статической памяти. И не следует путать массивы с контейнерами.
Единственное что отделяет динамический тип - где в итоге он будет расположен.
В программе, но вне любой из функций - статический (в статической области памяти)
В одной из функций (в т.ч. main) - автоматический (обычно в стеке)
Вне программы - динамический (в куче)
Да.
Олег Оболонин
Что "да"? Понимал бы ещё хоть слово в том, что написано, копипастер дешёвый...
На уровне нагрузки оперативной памяти, динамический массив будет тяжелей, его нужно выделять разумно.

1) при изменении числа в return слева, справа оно увеличивает число на 4 в инструкции [rbp+...]
2) создаются инструкции DWORD PTR, то есть кажется хранятся 32-битные значения под каждое число. при переполнении массива создалась только ассемблерная запись на 8 строчке
Похожие вопросы
- Объясните мне разное поведение sizeof для статической константы и динамического массива. C.
- Двумерный динамический массив с неизвестны количеством столбиков или строк
- Почему динамический массив напрямую в функцию передать нельзя, а динамический массив указателей можно?
- Динамический массив и указатель Си
- Задача по С++ ДИНАМИЧЕСКИЙ МАССИВ
- C++ динамический массив
- Программирование на C++ с использованием динамического массива
- Откуда взялся мусор в динамическом массиве char?
- C++ Одномерный динамический массив
- Размер динамического массива, передаваемого в функцию в C++.