Путаница с динамическим распределением массива
Я должен прочитать несколько значений от пользователя и сохранить их в массиве. Затем мне нужно создать массив, достаточно большой, чтобы хранить все эти значения. Используя некоторые функции, которые я написал, я сортирую /lsearch/bsearch через массив для заданных значений.
У меня уже написана моя программа и все, но для реализации статического массива. Я как-то запутался в том, где на самом деле использовать динамический массив.
Имеет смысл использовать его, когда пользователь начинает вводить значения, так как я не могу предположить, сколько значений он вводит, поэтому массив должен быть достаточно большим, чтобы его содержать. Также имеет смысл (вроде) использовать его, когда я создаю достаточно большой массив, который может содержать все значения (действует как копия первого массива).
Я не прошу никакого кода, все сделано, но на статическом подходе. Я просто пытаюсь визуализировать, где мне нужно использовать дарри здесь. Мои мысли:
- Когда пользователь впервые вводит значения
- Когда я копирую arr1 в новый arr2, он должен быть достаточно большим, чтобы вместить все значения arr1.
Я прав или нет в этом?
4 ответа
Начните с использования malloc
или же calloc
выделить массив некоторого известного начального размера и отслеживать текущую емкость в переменной.
Когда вы читаете значения в, если ваш массив недостаточно велик, то пользователь realloc
удвоить размер массива.
Если вы не уверены, сколько записей вставлено во время выполнения, я предлагаю вам использовать структуру данных связанного списка. Это сэкономит ваше использование памяти.
Лучшее решение - не копировать весь массив каждый раз, когда пользователь вводит значение. Требования к malloc и free будут тяжелыми и будут ухудшаться с большими массивами.
Вы должны рассчитать размер вашего массива с "количеством элементов в качестве входных данных
int * array = newArray (10);
int * newArray (int size) {вернуть malloc(size * sizeof(int)); }
Имейте в виду, что int*
это массив, так что вы все еще можете сделать array[3]
, Но, если вы централизуете хранилище с количеством используемых элементов и текущим размером, вы можете выделить несколько элементов и увеличиваться только при исчерпании доступных элементов.
struct DynamicIntArray {
int used;
int size;
int* storage
};
void add(struct DynamicArray* array, int value) {
if (used < size) {
(*array).storage[used] = value;
used++;
} else {
int newSize = size+10;
int* newStorage = (int*)malloc(newSize*sizeof(int));
int* oldStorage = (*array).storage;
for (int i = 0; i < size; i++) {
newStorage[i] = oldStorage[i];
}
(*array).storage = newStorage;
(*array).size = newSize;
free(oldStorage);
}
}
с таким примером. Вы должны быть в состоянии написать newDynamicIntArray(...)
функция и freeDynamicIntArray(struct DynamicIntArray* array)
функции и любые другие методы, которые вам небезразличны.
Я думаю, что вы задаете неправильный вопрос.
Вопрос в том:
Является ли динамический массив (непрерывный блок памяти) надлежащей структурой данных для хранения и обработки данных в вашем приложении?
Существует только одно особенно полезное приложение для массивов, и оно является ассоциативным массивом, что означает, что сам индекс массива имеет значение и может использоваться для получения правильного содержимого, которое вы ищете, с усилием O(1).
Например, список участников дорожек может быть сохранен в массиве, где индекс массива равен номеру дорожки. Это идеальная структура данных, если вы хотите визуализировать имена участников на треке. Это ужасная структура данных, если вы хотите отсортировать имена всех участников в алфавитном порядке.
Но в соответствии с описанием вашего приложения индекс массива не имеет для вас значения. Это указывает на то, что массив не лучший выбор.