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.