Я пишу реализацию массива с динамическим размером. Код компилируется без ошибок, но элементы массива не копируются должным образом. Кажется, что они просто стираются (перезаписываются нулями). Попытка вызвать геттер для элемента массива вызывает segfault.
Массив содержит указатели на некоторые объекты базового класса; это основное различие между моим кодом и примерами, которые я искал.
Это функция:
// Pointer to array of pointers
SomeClass** mainArray = new SomeClass[1];
int numItems = 0;
void AddItemDynamic(SomeClass* newVal) {
SomeClass** tempArray = new SomeClass*[numItems+1];
// Copying pointers to bigger array
for (int i = 0; i < numItems - 1; i++) {
tempArray[i] = mainArray[i];
}
numItems++;
// Adding the new value
tempArray[numItems] = newVal;
delete [] mainArray;
mainArray = tempArray;
}
Код должен скопировать элементы массива, а затем переназначить указатель на вновь созданный массив. Вместо этого указатель, кажется, установлен на что-то другое.
Почему бы вам не использовать вектор?
Почему вы создаете массив указателей вместо обычного массива?
Реализация безопасного и надежного динамического контейнера для исключений сложнее, чем вы думаете. К счастью, стандартная библиотека предоставляет std::vector
, std::deque
и другие контейнеры, которые тщательно протестированы и оптимизированы.
Как упоминалось другими, в стандартной библиотеке С++ уже есть «динамические массивы», поэтому используйте их только для упражнений или заданий, извлеките из них уроки, а затем выбросьте их.
Если в текущем массиве есть элемент numItems
, то цикл
for (int i = 0; i < numItems - 1; i++)
скопирует один меньше, чем numItems
элементов.
И когда вы добавляете новый элемент, вы выходите за границы нового массива, потому что вы увеличиваете numItems
до раннего.
Итак, две ошибки в одной и той же функции, по одной в каждом направлении.
И, как упоминалось в комментарий (спасибо Ayxan), первая ошибка «отклонение на единицу» будет означать, что при первом вызове этой функции два цикл копирования не произойдет. Это на самом деле хорошо, когда вы делаете это в первый раз, так как тогда нечего копировать, но во второй раз должно быть что-то для копирования, и все же цикл (в настоящее время) не запустится.
А учитывая, что numItems
инициализируется нулем, он, вероятно, становится отрицательным, и тело цикла полностью пропускается. Следовательно, все значения в массиве равны нулю.
Спасибо за четкий ответ, это именно то, что было неправильно. Результат копирования-вставки кода без его надлежащего прочтения; урок выучен.
SomeClass** mainArray = new SomeClass[1];
Что вы пытаетесь здесь сделать?