Home > Enterprise >  Why is the dynamically allocated memory released multiple times?
Why is the dynamically allocated memory released multiple times?

Time:11-02

I use mutex and static variable to make sure the dynamically allocated memory to be released only once. But they are still released multiple times. Why?

Thanks.

I have read some threads saying it's not necessary to explicitly release static pointers. But It would be good to understand why that happens.

// use C  -20
#include <iostream>
#include <vector>
#include <thread>
#include <atomic>

using namespace std;

class A {

private:
    static atomic_int *a;//=NULL;
    static std::mutex mutex_;
public:
    A() {
        std::lock_guard<std::mutex> lock(mutex_);
        if (!a) {
            a = new atomic_int[10]();
            std::cout << "creation A..." << std::endl;
        }
    }

    ~A() {
        std::lock_guard<std::mutex> lock(mutex_);
        if (a) {
            delete[] a;
            //delete a;
            a = NULL;
            std::cout << "deletion A..." << std::endl;
        }

    }

    A(A &t) {
        cout << "copy..." << endl;
    }


};

atomic_int *A::a = NULL;
std::mutex A::mutex_;

class B {
private:
    static A *a;
    static std::mutex mutex_;

public:
    B() {

        std::lock_guard<std::mutex> lock(mutex_);
        if (!a) {
            a = new A();
            std::cout << "creation B ..." << std::endl;
        }

    }

    ~B() {
        std::lock_guard<std::mutex> lock(mutex_);
        if (a) {
            cout << "Delete B" << endl;
            delete a;
            a = NULL;
        }
    }

    void run() {
        std::cout << "Hello from B" << std::endl;
    }

    thread take_action() {
        return thread([this] { run(); });
    }
};

A *B::a = NULL;
std::mutex B::mutex_;

int main() {
    cout << "Hello World" << endl;

    vector<B> b;
    vector<std::thread> b_thread;

    for (int i = 0; i < 3;   i) {
        b.push_back(B());

    }

//
//    B b1, b2;
    for (int i = 0; i < 3;   i) {
        b[i].run();
    }

    for (int i = 0; i < b.size();   i) {
        b_thread.push_back(b[i].take_action());

    }

    for (int i = 0; i < b_thread.size();   i) {
        b_thread[i].join();
    }

//    b1.run();

//    b2.run();

    return 0;
}

Result:

Hello World
creation A...
creation B ...
Delete B
deletion A...
creation A...
creation B ...
Delete B
deletion A...
creation A...
creation B ...
Delete B
deletion A...
Hello from B
Hello from B
Hello from B
Hello from B
Hello from B
Hello from B

CodePudding user response:

Because when you use such codes

    for (int i = 0; i < 3;   i) {
        b.push_back(B());

    }

You will create three B objects, they are temporary variables, and they will destruct after push_back execute, so you allocate A pointer and delete it three times.

  • Related