没有引用的对象的内存会自动清除吗?

时间:2021-07-15 07:51:30

标签: c++ oop arduino

我知道,这是一个愚蠢的问题,但是我有几个类扩展了另一个类,并且我有一个变量 (Test* currentTest),其中保存了其中一个类的一个实例。它总是会改变变量中的内容,经过几次更改后,整个程序就会崩溃(重新启动或只是冻结),我想知道内存是否真的被自动清除了,或者我只是愚蠢。

编辑:这是用于测试的草图。它可以正常工作几秒钟,但随后崩溃(可能是因为 RAM 已满)。这基本上就是我的程序正在做的事情,只是有更多的类和更新函数来实际做一些事情。

class Test {
  public:
    virtual void update();
};
void Test::update() {}

class TestA : public Test {
  public:
    virtual void update();
  private:
    int a = 0;
    int abc[50]; // allocate a lot of memory, just like in the actual program
};

class TestB : public Test {
  public:
    virtual void update();
  private:
    int a = 0;
    int abc[20]; // allocate a lot of memory, just like in the actual program
};

Test* currentTest;

void setup() {
  Serial.begin(9600);
  currentTest = new TestA();
  Serial.println("Start!");
}

void loop() {
  currentTest->update();
  delay(100);
}

void TestA::update() {
  Serial.println("Running A");
  a++;
  if(a >= 5) {
    currentTest = new TestB();
  }
}

void TestB::update() {
  Serial.println("Running B");
  a++;
  if(a >= 5) {
    currentTest = new TestA();
  }
}

2 个答案:

答案 0 :(得分:2)

您一直在泄漏内存,直到内存用完为止。每个 new 都应该有一个 delete。如果我们只看 update 方法而忽略所有其他方法,您应该delete 旧的 currentTest,然后再分配一个新的:

void TestA::update() {
  Serial.println("Running A");
  a++;
  if(a >= 5) {
    delete currentTest;
    currentTest = new TestB();
  }
}

然而,我们不能忽视所有其他的! currentTest 是指向当前对象的指针,您不能在成员函数中调用析构函数而不会遇到问题。 Test 对象不应该负责删除自己。您应该有其他东西来管理 Test。实际上你应该使用智能指针,尽管没有你可以使用这样的东西:

struct TestManager {
     Test * test = nullptr;
     int counter = 0;
     void update() {
          if (test) {
              test->update();
              ++counter;
          }
          if (test && counter == 5) {
              delete test;
              test = new TestA;
          }
     }
 };

然而,您真的应该使用智能指针,而不是手动管理原始指针。在上面我总是创建一个 TestA,而你想创建不同子类的实例,这可能是一个不同的问题。

答案 1 :(得分:1)

没有。可能你需要 std::shared_ptr<>