创建对象的第二个实例会更改整个类的行为(C ++)

时间:2019-03-27 13:18:36

标签: c++ object initialization

我用C ++编写了一个Arduino库,其中包含一个迭代器类。如果我一直使用相同的实例遍历它,那么它将按预期工作。如果创建第二个实例,它将使存储的对象数量增加一倍。

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 个答案:

答案 0 :(得分:2)

WayPointStack wps = *(new WayPointStack());

必须

WayPointStack wps;

因为这足够了,可以消除内存泄漏


 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

答案 1 :(得分:0)

这行似乎有内存泄漏:

val date = Date() val cal = Calendar.getInstance() cal.time = date cal.add(Calendar.MONTH, 1) val datePlusOneMonth: Date = cal.time ;

好像您正在堆上创建WPCommand,然后扔掉指针并返回一个副本!!!

该示例并非最少且完整,因此很难给出更好的指示。