#c
Вопрос:
У меня есть вызываемый класс Rectangle
, который содержит два указателя на объекты этого класса Point2D
.
class Rectangle: public GeoObjekt
{
private:
Point2D* lu;
Point2D* ro;
public:
Rectangle(Point2D lu, Point2D ro);
}
Rectangle::Rectangle(Point2D lu, Point2D ro) {
this->lu = amp;lu;
this->ro = amp;ro;
}
Чтобы создать объект этого класса, я вызываю следующую строку:
Rectangle rectangle(Point2D(0, 0), Point2D(2, 1));
Конструктор работает нормально, но когда я пытаюсь получить доступ Point2D* lu;
или Point2D* ro;
, я получаю исключение нарушения доступа:
Исключение, выданное при 0xFEDC8589 в Rectangle.exe: 0xC00005: Нарушение доступа при выполнении в позиции 0xFEDC8589.
Я проверил это с помощью отладчика, и значения внутри Point2D* lu;
или Point2D* ro;
полностью отличаются от значений, которые у них были изначально. Они меняются после выхода из конструктора.
Может кто-нибудь сказать мне, что я делаю не так?
Примечание: Строка Rectangle rectangle(Point2D(0, 0), Point2D(2, 1));
должна оставаться такой, какая она есть.
Комментарии:
1. Вы понимаете, что такое болтающийся указатель?
2. «… есть класс под названием rectangle, который содержит указатели…»
Point2D
вместо этого удерживайте.3. Быстрый совет: используйте указатели как можно меньше в современном C . Никогда не используйте
operator new
, кроме как при размещении новых выражений, и всегда предпочитайте интеллектуальные указатели и контейнеры, такие какstd::vector
иstd::array
, необработанным указателям и массивам C. Делайте это постоянно, и вы заметите, что ваши программы в основном никогда не будут сбоить, если вы не сделаете что-то действительно плохое. В настоящее время в C 17 и C 20 я в основном использую указатели в качестве заменыstd::optional<Tamp;>
(что не является законным).4. @mcilloni хорошо. Спасибо за подсказку!
Ответ №1:
Измените участников lu
и ro
станьте Point2D
вместо Point2D*
них .
Point2D
S, которые вы указали в конструкторе, уничтожаются в следующей строке, поэтому ваши указатели в конечном итоге ни на что не указывают (висячие указатели).
Комментарии:
1. Это сработало. Я немного смущен, почему это болтающийся указатель, но я буду его искать. Спасибо!
2. @медленно Вы передаете временные объекты конструктору, а затем сохраняете указатели на объекты. Объекты автоматически уничтожаются после завершения работы конструктора, таким образом, указатели остаются указывающими на освобожденную память. Вот почему указатели болтаются. Что предлагает Camwin, так это полностью избавиться от указателей, чтобы конструктор вместо этого создавал копии временных объектов.
3. Еще одна причина этого изменения: вы действительно хотите хранить сами углы (координаты), а не только то, где они находятся в памяти (указатели).
4. @RemyLebeau Я думал, что только доступ будет «удален», но сам объект все равно будет существовать. Большое спасибо!
5. @медленно вы должны прочитать о сроке службы и области применения. В операторе
Rectangle rectangle(Point2D(0, 0), Point2D(2, 1));
дваPoint2D
объекта выходят за пределы области действия, заканчивают свое время жизни и, таким образом, уничтожаются, когда вызывающий операторrectangle()
завершен (т. Е. Когда;
достигнут).