C++开发时,有时会遇到程序崩溃的情况,今天和大家分享一个SIGSEGV崩溃问题。
SIGSEVG问题一般是访问了非法内存导致。
问题场景还原
两个so,a.so和b.so,b.so依赖a.so
a模块有三个文件:
- Net.h
- Net.cpp
- Android.mk
// Net.h
// 注意Net类的声明中有宏定义MACRO包含的成员
class Net{
public:
Net(){}
void PrintName();
#ifdef MACRO
void DoSthWithMACRO(){}
#endif
private:
int id_;
#ifdef MACRO
vector<int> vec_;
#endif
string name_;
};
// Net.cpp
Net::PrintName(){
// 访问成员变量name_
cout<<this->name_<<endl;
}
// Android.mk
// 编译文件中定义了MACRO
CFLAGS += -DMACRO
b模块有三个文件:
- User.h
- User.cpp
- Android.mk
// User.h
// User类中有Net成员
#include Net.h
class User{
public:
void PrintNetName();
private:
// 拥有Net成员
Net* net_;
};
// User.cpp
User::PrintNetName(){
net_ = new Net();
net_->PrintName();
}
// Android.mk
// 编译文件中并没有定义MACRO宏
由于两个模块(so)中一个定义了宏MACRO,一个没有定义,就会导致class Net在两个模块的声明有差异:a.so中比b.so中的class Net多了
#ifdef MACRO
...
#endif
之间的内容。
差异如下:
在a.so中Net的定义是:
class Net{
public:
Net(){}
void PrintName(){
// 访问成员变量name_
cout<<this->name_<<endl;
}
#ifdef MACRO
void DoSthWithMACRO(){}
#endif
private:
int id_;
#ifdef MACRO
vector<int> vec_;
#endif
string name_;
};
在b.so中的Net的定义是:
class Net{
public:
Net(){}
void PrintName(){
// 访问成员变量name_
cout<<this->name_<<endl;
}
private:
int id_;
string name_;
};
因此在b.so中创建的Net对象并调用a.so中Net.cpp的PrintName()访问成员变量name_时就会崩库。因为内存地址对应不上。
网友评论