Создание второго экземпляра объекта изменяет поведение всего класса (C ++) - PullRequest
0 голосов
/ 27 марта 2019

Я написал библиотеку Arduino на C ++, которая содержит класс итераторов.Если я повторяю его все время, используя один и тот же экземпляр, он работает как положено.Если я создам для этого второй экземпляр, он удвоит количество хранимых объектов.

WayPointStack wps = *(new WayPointStack());
wps.AddWP(1, 20);
wps.AddWP(2, 420);

WPCommand c1 = wps.GetNextWP(); //  Stack length: 2, correct
c1 = wps.GetNextWP();           //

WPCommand c1 = wps.GetNextWP(); //  Stack length: 4, not correct
WPCommand c2 = wps.GetNextWP(); //


  WPCommand WayPointStack::GetNextWP()
{
    Serial.println("Pointer = ");
    Serial.println(pointer);
    Serial.println("Length = ");
    Serial.println(_length);
    if (pointer < _length){
        pointer++;
        return _wp[pointer-1];
    }
    return *(new WPCommand(_END, 10000));
}

void WayPointStack::AddWP(int target, int time)
{
    if (_length == arrSize)
        return;
    _wp[_length] = *(new WPCommand(target, time));
    _length++;
}

WayPointStack::WayPointStack()
{
  _wp = new WPCommand[arrSize];
  _length = 0;
  pointer = 0;
}

WPCommand::WPCommand(int target, int time)
{
    _target = target;
    _time = time;
}

Может кто-нибудь мне это объяснить?

Ответы [ 2 ]

2 голосов
/ 27 марта 2019
WayPointStack wps = *(new WayPointStack());

должно быть

WayPointStack wps;

, поскольку этого достаточно и это устраняет утечку памяти


In

 WPCommand WayPointStack::GetNextWP()
 {
     ...
     return *(new WPCommand(_END, 10000));
 }

вы создаете другую утечку памяти, может быть, не возвращать элемент, но его адрес позволяет вернуть nullptr при ошибке?

 /*const ?*/ WPCommand * WayPointStack::GetNextWP()
 {
     Serial.println("Pointer = ");
     Serial.println(pointer);
     Serial.println("Length = ");
     Serial.println(_length);
     if (pointer < _length){
       return &_wp[pointer++];
     }
     return nullptr;
 }

иначе использовать статическую переменную:

  WPCommand WayPointStack::GetNextWP()
  {
      ...
      static WPCommand error(_END, 10000);
      return error;
  }

В

void WayPointStack::AddWP(int target, int time)
{
    if (_length == arrSize)
        return;
    _wp[_length] = *(new WPCommand(target, time));
    _length++;
}

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

 void WayPointStack::AddWP(int target, int time)
 {
     if (_length == arrSize)
         return;
     _wp[_length]._target = target, time));
     _wp[_length]._time = time;
     _length++;
 }

вы не сигнализируете об ошибке, когда не можете добавить новый элемент, что будет возвращать bool , оценивающий false при ошибке и true, когда вы можете добавить:

 bool WayPointStack::AddWP(int target, int time)
 {
     if (_length == arrSize)
         return false;
     _wp[_length]._target = target;
     _wp[_length]._time = time;
     _length++;
     return true;
 }

НаконецПочему вы не используете std::vector для _wp

0 голосов
/ 27 марта 2019

Похоже, у вас утечка памяти в этой строке:

return *(new WPCommand(_END, 10000));

Похоже, вы создаете WPCommand в куче, затем выбрасываете указатель и возвращаете копию !!!

Пример не является минимальным и полным, поэтому трудно дать лучшие указатели.

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