我有一个 C++ 应用程序,它有一个主线程和一个 Poco::Timer 来触发回调,该回调使用 Poco::FileOutputStream 写入文件:
FileOutputStream file("test.txt", ios::binary); <-- *Access violation reading location here*
file.write(reinterpret_cast<char *>(&data), sizeof(data));
file.close();
代码总是在第一行失败,这是调用堆栈:
testProject.exe!std::ctype::widen(char _Byte=' ') Line 1716 + 0xf bytes C++ testProject.exe!std::basic_ios >::widen(char _Byte=' ') Line 126 C++ testProject.exe!std::basic_ios >::init(std::basic_streambuf > * _Strbuf=0x038ef700, bool _Isstd=false) Line 135 + 0xa bytes C++ testProject.exe!std::basic_ostream >::basic_ostream >(std::basic_streambuf > * _Strbuf=0x038ef700, bool _Isstd=false) Line 54 C++ testProject.exe!Poco::FileOutputStream::FileOutputStream(const std::basic_string,std::allocator > & path="c:\Projects\TestProject\test.txt", int mode=32) Line 93 + 0xa3 bytes C++ testProject.exe!OPC_Server::OnTimer(Poco::Timer & timer={...}) Line 3656 + 0x13 bytes C++ testProject.exe!Poco::TimerCallback::invoke(Poco::Timer & timer={...}) Line 212 + 0x14 bytes C++ testProject.exe!Poco::Timer::run() Line 197 + 0x19 bytes C++ testProject.exe!Poco::PooledThread::run() Line 200 + 0x15 bytes C++ testProject.exe!Poco::`anonymous namespace'::RunnableHolder::run() Line 57 + 0x17 bytes C++ testProject.exe!Poco::ThreadImpl::runnableEntry(void * pThread=0x00db6afc) Line 207 + 0x20 bytes C++ testProject.exe!_callthreadstartex() Line 348 + 0xf bytes C testProject.exe!_threadstartex(void * ptd=0x00db6d00) Line 331 C
跟踪堆栈,计时器线程似乎读取 xlocale 内部 header 中调用堆栈顶部的初始化_Byte :
_Elem __CLR_OR_THIS_CALL widen(char _Byte) const
{ // widen char
return (do_widen(_Byte)); <-- failed: Access violation reading location
}
ios 标准 header 中堆栈中的第二个条目:
_Elem __CLR_OR_THIS_CALL widen(char _Byte) const
{ // convert _Byte to character using imbued locale
const _Ctype& _Ctype_fac = _USE(getloc(), _Ctype);
return (_Ctype_fac.widen(_Byte)); <-- call the top of the stack
}
ios 标准 header 中堆栈中的第三个条目:
protected:
void __CLR_OR_THIS_CALL init(_Mysb *_Strbuf = 0,
bool _Isstd = false)
{ // initialize with stream buffer pointer
_Init(); // initialize ios_base
_Mystrbuf = _Strbuf;
_Tiestr = 0;
_Fillch = widen(' '); <-- call the second entry
但非常奇怪的是,同样的代码在主线程上使用时运行良好,没有任何错误。
是否需要设置任何权限设置才能使 Poco::Timer 正常运行?还是我遗漏了一些非常明显的东西?感谢您的帮助。
编辑:--------------------
Poco 版本:1.7.3
平台:windows
最佳答案
事实证明,应用程序在创建计时器后立即退出,但退出没有完全完成,所以看起来应用程序仍在运行并且计时器仍在滴答作响,而实际上一些资源已经被释放,这会导致错误。
MS 的 _tmain() 显然比 main() 做了一些额外的事情。
抱歉,调用 _tmain() 的不是 _tmain(),而是 _tmainCRTStartup。当 _tmain() 退出时,会运行其他清理代码,我的项目不会以某种方式终止并且应用程序似乎仍在“正在运行”。
关于c++ - 多线程访问冲突读取位置C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37479080/