Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 奇异seg故障问题_C++ - Fatal编程技术网

C++ 奇异seg故障问题

C++ 奇异seg故障问题,c++,C++,您好 我有一个奇怪的seg故障问题。我的应用程序在运行时转储核心文件。挖掘后,我发现它死在这个街区: #include <lib1/c.h> ... x::c obj; obj.func1(); 在代码库中搜索后,我发现其他人在同一命名空间中定义了一个同名类,但在另一个库lib2中定义了一个类名,如下所示: namespace x { struct c { c(); ~c(); voi

您好

我有一个奇怪的seg故障问题。我的应用程序在运行时转储核心文件。挖掘后,我发现它死在这个街区:

#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。这种有趣的行为带来了几个问题:

  • 为什么它会起作用?我希望在链接lib2(取决于lib1)时会出现“多个定义”错误,但从未出现过这样的错误。除了在运行时转储内核外,应用程序似乎正在执行func1中定义的操作

  • 在附加调试器之后,我发现我的应用程序在lib2中调用类c的ctor,然后调用func1(在lib1中定义)。当超出范围时,它调用lib2中c类的dtor,其中发生seg错误。有人能教我怎么会这样吗

  • 如何防止此类问题再次发生?有没有我可以使用的C++语法?< /p>

  • 忘了提到我在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;  
        };  
    }