Я использую библиотеку C из C ++ и, следовательно, я имею дело со многими необработанными указателями. Я хочу создать указатель на объект (например, A
), а затем передать указатель на другой объект (например, B
) для выполнения чего-то специализированного с. Затем я хочу, чтобы жизнь Б закончилась, но А продолжала делать другие вещи с указателем.
Следующий код выдает ошибку double free or corruption
и затем завершается с кодом 139
. Однако, когда я удаляю деструкторы, этого не происходит (что не имеет для меня большого смысла, поскольку я думал, что любой объект, использующий необработанные указатели, должен реализовывать свой собственный деструктор для приведения в порядок после себя).
Почему это происходит и есть ли лучшая стратегия для достижения вышеизложенного?
#include <iostream>
#include <sstream>
using namespace std;
struct World { // potentially containing a large amount of data
int a;
int b;
const char *c;
};
class B {
private:
World *world_;
public:
std::string doSomethingCleverWithWorld(){
std::ostringstream os;
os << world_->c << " = " << world_->a + world_->b <<std::endl;
return os.str();
}
explicit B(World *world) {
world_ = world;
}
~B(){
// I want the pointer to world_ to persist after use of B
// delete world_;
}
};
class A {
private:
World *world_;
public:
explicit A(World *world) {
world_ = world;
}
~A() {
delete world_;
}
A(const A &a) {
this->world_ = a.world_;
}
A(A &&a) noexcept {
this->world_ = a.world_;
}
A &operator=(const A &a) {
if (this != &a) {
this->world_ = a.world_;
}
return *this;
}
A &operator=(A &&a) noexcept {
if (this != &a) {
this->world_ = a.world_;
}
return *this;
}
std::string doCleverStuff(){
B b(world_);
return b.doSomethingCleverWithWorld();
}
};
int main() {
World world{
4, 6, "stuff"
};
A a(&world);
std::string clever = a.doCleverStuff();
std::cout << clever << std::endl;
return 0;
};
Выход
stuff = 10
double free or corruption (out)
Process finished with exit code 134