【发布时间】:2017-01-07 15:52:30
【问题描述】:
如果我更改变量定义的顺序,我的程序会崩溃,有人知道为什么吗? 按照这个顺序,它将按我的预期运行:
class xThread
{
public:
xThread();
virtual ~xThread() {}
bool thread_start();
virtual bool thread_init(){return true;}
virtual void thread_stop();
void thread_setState(ThreadState s) {state = s;}
ThreadState thread_getState( ){return state;}
static void *thread_run(void *param);
void setName(const char *n);
char name[MAX_NAMESIZE];
protected:
volatile ThreadState state;
virtual void thread_proc()=0;
private:
pthread_t pid;
};
如果我改变变量“name”和“state”的定义顺序,它会崩溃:
class xThread
{
public:
xThread();
virtual ~xThread() {}
bool thread_start();
virtual bool thread_init(){return true;}
virtual void thread_stop();
void thread_setState(ThreadState s) {state = s;}
ThreadState thread_getState( ){return state;}
static void *thread_run(void *param);
void setName(const char *n);
protected:
volatile ThreadState state;
virtual void thread_proc()=0;
private:
pthread_t pid;
char name[MAX_NAMESIZE];
};
这是gdb堆栈,看起来很奇怪
0 0x00007f34dfaeff72 in _int_malloc () from /lib64/libc.so.6
1 0x00007f34dfaf187c in malloc () from /lib64/libc.so.6
2 0x00007f34e03aa0cd in operator new(unsigned long) () from /lib64/libstdc++.so.6
3 0x00007f34e15d93b1 in log4cxx::Logger::forcedLog(log4cxx::helpers::ObjectPtrT<log4cxx::Level> const&, std::string const&, log4cxx::spi::LocationInfo const&) const () from /lib64/liblog4cxx.so.10
4 0x000000000081e615 in xServer::v_final (this=0x19921b0) at xlib/xServer.cpp:112
5 0x000000000082218c in xServer::run (this=0x19921b0) at xlib/xServer.cpp:411
6 0x00000000007b2ebc in main (argc=4, argv=0x7fff46d5f258) at SceneServer.cpp:152
“name”是我用来标记每个线程的变量。它是在线程启动之前定义的,在线程终止时打印出来。
main.cpp:
HttpClientThread client;
client.setName("HttpClientThread ");
client.thread_start();
xThread.cpp:
xThread::xThread()
{
thread_setState(THREAD_INIT);
bzero(name, sizeof(name));
pid = 0;
}
xThread::~xThread()
{
LOG4CXX_DEBUG(::log4cxx::Logger::getLogger("main"), name);
}
void xThread::setName(const char *n)
{
if (!n) return;
bzero(name, sizeof(name));
strncpy(name, n, MAX_NAMESIZE-1);
}
bool xThread::thread_start()
{
if (!thread_init()) return false;
int ret = pthread_create(&pid, NULL, &thread_run, (void *)this);
if (ret == 0)
{
return true;
}
else
{
return false;
}
}
void xThread::thread_stop()
{
if (thread_getState()==THREAD_INIT)
thread_setState(THREAD_FINISH);
if (thread_getState()==THREAD_RUN)
thread_setState(THREAD_STOP);
}
void *xThread::thread_run(void *param)
{
xThread *t = (xThread *)param;
t->thread_proc();
t->thread_setState(THREAD_FINISH);
return 0;
}
【问题讨论】:
-
您能发布调试器、gdb 和/或小型工作示例的输出吗?
-
这取决于如何定义
xThread()w.r.t。初始化。可能name[]在那里被一些在它之前声明的变量使用。发布构造函数的定义。 -
您是否拥有 xThread.cpp 的源代码并在您的项目中编译它?还是您只是在使用一个库,而发布的 sn-p(您要修改的那个)是与库一起分发的标头的副本?
-
请注意,
volatile并不代表您认为的意思。 -
最有可能:您在使用
name时遇到了一个错误。在pid之前定义name,结果是部分覆盖pid。在pid之后定义name,结果是您写入了为xThread分配的数据块,malloc检测到并抱怨。当您的意思是name[MAX_NAMESIZE-1]=0;时,您是在做name[MAX_NAMESIZE]=0;吗?
标签: c++ crash initialization class-members