C++ 奇异seg故障问题
您好 我有一个奇怪的seg故障问题。我的应用程序在运行时转储核心文件。挖掘后,我发现它死在这个街区:C++ 奇异seg故障问题,c++,C++,您好 我有一个奇怪的seg故障问题。我的应用程序在运行时转储核心文件。挖掘后,我发现它死在这个街区: #include <lib1/c.h> ... x::c obj; obj.func1(); 在代码库中搜索后,我发现其他人在同一命名空间中定义了一个同名类,但在另一个库lib2中定义了一个类名,如下所示: namespace x { struct c { c(); ~c(); voi
#include <lib1/c.h>
...
x::c obj;
obj.func1();
在代码库中搜索后,我发现其他人在同一命名空间中定义了一个同名类,但在另一个库lib2中定义了一个类名,如下所示:
namespace x
{
struct c
{
c();
~c();
void func2();
vector<string> strs_;
};
}
x::c::c()
{
}
x::c::~c()
{
}
名称空间x
{
结构c
{
c();
~c();
void func2();
向量strs;
};
}
x::c::c()
{
}
x::c::~c()
{
}
我的应用程序链接到lib2,它依赖于lib1。这种有趣的行为带来了几个问题:
忘了提到我在RHEL4上使用的是g++4.1,非常感谢 只是一个猜测,但我没有看到任何
使用名称空间x代码>因此,它可能使用一个名称空间而不是另一个名称空间?随着模板的出现,有必要允许使用相同名称的代码体的多个定义;编译器无法知道在另一个编译单元(即源文件)中是否已经生成了相同的模板代码。当链接器发现这些重复项时,它假定它们是相同的。你的责任在于确保它们是正确的——这被称为。1
违反“一个定义规则”不必由编译器诊断。事实上,当您将多个对象文件链接在一起时,通常只在链接时才知道它们
在链接时,有关原始类定义的信息可能不再存在(在编译器步骤之后不需要这些信息),因此,通常不容易向用户标记一个类的多个定义
二,
一旦你有了两个不同的定义,几乎任何事情都可能发生,你就处于未定义行为的领域。不管发生什么,这都是可能的结果
三,
最明智的做法是与团队的其他成员沟通。商定谁将使用哪些名称空间,您就不会遇到这些问题。否则,您将在整个项目上使用文档工具或静态分析工具。许多这样的工具将能够诊断多个不一致的类定义。在链接器级别,这是库插入。不幸的是,有效的符号绑定取决于链接器命令行上对象文件的顺序(这是历史的)
从您的描述来看,lib1
在链接器参数列表中位于第一位,lib2
位于第二位,并插入lib1
中的符号。这解释了从lib2
调用构造函数和析构函数,但从lib1
调用func1
(因为lib2
中没有func1
-派生符号,所以没有“隐藏”,所以调用绑定到lib1
)
这个特殊问题的解决方案是颠倒链接器调用命令上库的顺序。关于一个定义规则有很多答案。然而,对我来说,这看起来更像是一个丢失的副本构造函数
详细说明:
如果在对象上调用复制构造函数,则会出现内存泄漏。这是因为delete将在同一组指针上调用两次
namespace x
{
struct c
{
c() {
}
~c() {
for ( int i = 0; i < _data.size(); ++i )
delete _data[i];
}
c(const c & rhs) {
for (int i=0; i< rhs.size(); ++i) {
int len = strlen(rhs[i]);
char *mem = malloc(len + 1);
strncpy(mem, rhs[i], len + 1);
_data.push_back(mem);
}
void fun1();
vector<char *> _data;
};
}
名称空间x
{
结构c
{
c(){
}
~c(){
对于(int i=0;i<_data.size();++i)
删除_数据[i];
}
主管(施工主管和rhs){
对于(int i=0;i
这并不能真正解释缺少“重复定义”链接器错误的原因。有趣的是,我从来没有想过复制链接器会是一个问题。你能详细说明一下吗?
namespace x
{
struct c
{
c();
~c();
void func2();
vector<string> strs_;
};
}
x::c::c()
{
}
x::c::~c()
{
}
namespace x
{
struct c
{
c() {
}
~c() {
for ( int i = 0; i < _data.size(); ++i )
delete _data[i];
}
c(const c & rhs) {
for (int i=0; i< rhs.size(); ++i) {
int len = strlen(rhs[i]);
char *mem = malloc(len + 1);
strncpy(mem, rhs[i], len + 1);
_data.push_back(mem);
}
void fun1();
vector<char *> _data;
};
}