Нарушение прав доступа при попытке доступа к переменным-членам объекта в массиве - PullRequest
0 голосов
/ 01 мая 2019

В моей программе / задании «симуляция зоопарка» включает в себя динамические массивы [не могут использовать векторы] объектов животных различных видов, которые наследуются от базового класса Animal. Но моя проблема кажется очень простой (надеюсь):

Я использовал конструкцию

Animal **arr = new Animal*[10];

, но чтение arr[0]->getAge() вызывает нарушение доступа.

Я пытаюсь одновременно понять указатели, но также, возможно, получить правильный код для предварительного понимания из-за крайнего срока.

Я пробовал

*arr = new Animal[10]

но возникают проблемы, когда я хочу добавить / изменить объекты в массиве или удалить массив. Возможно,

** новый *

работает только с определенными типами переменных, а не с объектами классов. Я могу установить массив с

*arr = new Animal[10];

формирование, но потом, когда я пытаюсь установить что-то вроде

 arr[05] = to a new Tiger object, 

ничего не меняется, поэтому я бью стену.

В основном мне нужно инициализировать массив объектов Animal, а затем добавить в массив объекты унаследованных классов. Спасибо за любую информацию и извинения за мою новизну.

Ответы [ 2 ]

3 голосов
/ 01 мая 2019

В

Animal **arr = new Animal*[10];

Animal **arr объявляет указатель на указатель. new Animal*[10] выделяет 10 указателей на Animal с. Эти 10 указателей не инициализированы и нигде не безопасны для использования.

arr[0]->getAge();

получает первые 10 указателей и пытается использовать то, на что указывает. Поскольку он не указывает на действительный Animal, все может произойти. В этом случае оказывается, что программа вылетает. Это один из лучших результатов, потому что он сразу делает ошибку заметной.

Теперь предположим, что Tiger происходит от Animal

class Tiger: public Animal
{
    // definition of Tiger
}

тогда можно позже

arr[0] = new Tiger;

чтобы указать первый из 10 указателей на действительный экземпляр Tiger, а затем вы можете

arr[0]->getAge();

Когда вы закончите, не забудьте delete все Animal s и delete[] arr.

Sidenote:

Не пишите такой код. Это чрезвычайно подвержен ошибкам. Вместо этого используйте преимущества контейнеров стандартной библиотеки, таких как std::vector, и предпочитайте умные указатели, такие как std::unique_ptr, для управления динамической памятью программы. Пример: * * тысяча тридцать пять

std::vector<std::unique_ptr<Animal>> arr;

Создает массив с изменяемым размером Animal с, который будет автоматически удаляться, когда arr больше не нужен и выходит из области видимости.

Добавление Tiger будет выглядеть как

arr.push_back(std::make_unique<Tiger>());

Это выглядит более громоздким, но избавляет вас от необходимости искать точные места в коде, где вы должны delete свои ресурсы, и быть абсолютно уверенным, что они delete d.

0 голосов
/ 01 мая 2019

Вы выделили массив указателей, но на самом деле вы не выделили никаких объектов для этих указателей.Так что arr[0]->... - неопределенное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...