我有以下类结构,最初抛出了一个段错误。我已经解决了这个问题,但不完全理解为什么代码最初通过段错误。我有一个类B
,一个A
的子类,它,A
初始化列表中的对象(InternalA
(后 的构造函数,称为Run()
方法,该方法在调用阻塞方法(io_service_.Run()
(之前在InternalA
(InternalA.Start()
(上调用方法,因此B
的构造函数从未实际返回过。
然后一个单独的线程将尝试访问B
,并调用B->SendMsg()
,但是InternalA
的所有内部状态都会被破坏。我通过从构造函数中删除阻塞Run()
方法调用并在之后调用它来解决此问题。
代码告诉我,InternalA
对象确实被正确初始化,但是在调用b->SendMsg
时,InternalA
完全损坏了。
使用new
运算符,"真实"地址仅在返回构造函数后分配给B*
指针的问题(即使当我在主线程中检查 b 的地址时,它不再是 null(。如果我改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
}
在将值分配给b
之前,必须先计算该值。在您的情况下,此计算 (new B()
( 永远不会返回,因此您在另一个线程中读取b
的未初始化内容。
另外,"然后一个单独的线程会尝试访问 B"?没有任何组织检查以查看"B"是否真的存在?使用这种方法,您将遇到许多难以找到的错误。