我有以下类结构,最初抛出了一个段错误。我已经解决了这个问题,但并不完全理解为什么代码最初会通过段错误。我有一个B
类,A
的子类,
在A
初始化初始化列表中的对象(InternalA
)之后
构造函数,称为Run()
方法,在调用阻塞方法(InternalA
)之前调用InternalA.Start()
(io_service_.Run()
)上的方法,因此B
的构造函数从未实际返回。
然后,单独的线程将尝试访问B
,并调用B->SendMsg()
,但是
所有InternalA
的内部状态都将被破坏。我通过从构造函数中删除阻塞Run()
方法调用并在之后调用它来解决问题。
代码向我显示InternalA
对象确实已正确初始化,但在调用b->SendMsg
时,InternalA
已完全损坏。
使用new
运算符," real"返回构造函数后,地址仅被分配给B*
指针(即使在我检查主线程中的b的地址时,它也不再为null)。如果我改为malloced B
,然后调用*b = B()
,它仍然是一个问题,或者这将是特定于架构的?
class B: public A
{
B(): A(arg1, arg2) { Run(); }
};
class A {
A(): InternalA()... {}
Run() {
InternalA.Start();
// Method does not terminate
io_service_.Run();
}
};
class InternalA {
InternalA(): io_service_(), map_(), id_(5) {}
void Start() {
std::cout << connections_.size() << std::endl;
}
void SendMsg() {
std::cout << connections_.size() << std::endl;
}
private:
boost::asio io_service_
std:map<X,Y> map_;
int id_;
};
int main() {
B* b = null;
std::thread t([&b] {b = new B()}); // Run() method gets called
usleep(200000);
b->SendMsg(); // All objects in InternalA are corrupted (point to invalid addresses
}
答案 0 :(得分:-1)
在为b
指定值之前,必须先计算该值。在您的情况下,此计算(new B()
)永远不会返回,因此您在另一个线程中读取b
的未初始化内容。
此外,&#34;然后一个单独的线程将尝试访问B&#34;?没有任何检查组织,看看是否&#34; B&#34;实际上在那里?使用这种方法会有很多难以发现的错误。