Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
353 views
in Technique[技术] by (71.8m points)

Creating a second instance of an object changes whole class behavior (C++)

I have written an Arduino library in C++ that contains an iterator class. If I iterate through it using the same instance all the time, it works as expected. If I create a second instance to do so, it will double the amount of stored objects.

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;
}

Can someone explain this to me?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
WayPointStack wps = *(new WayPointStack());

must be

WayPointStack wps;

because it is enough and that removes the memory leak


In

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

you create an other memory leak, may be do not return the element but its address allowing you to return nullptr on error ?

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

else use a static var :

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

In

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

you create an other memory leak, you just need to initialize the entry :

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

you do not signal the error when you cannot add a new element, what about to return a bool valuing false on error and true when you can add :

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

Finally Why do you not use a std::vector for _wp


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...