2009-12-07 82 views
0

我有一个C++应用程序(严重缩短,如下所示);从特定库实例化对象时出现分段错误

#include <iostream> 
#include "MyClass.h" 

void foobar() 
{ 
MyClass a; 
} 

int main(int argc, char** argv) 
{ 
std::cout << "Hello world!\n"; 

return 0; 
} 

其中“MyClass”是在静态链接库(.a)中定义的。

但是,这个应用程序Segfaults开始的瞬间,我永远不会到达“Hello world”。

我可以从同一个库中创建一个接口的实例,但我无法创建实现该接口的类的实例。即;

void foobar() 
{ 
IMyClass a; // Having this in the application works. 
MyClass b; // Segfault if this is in. 
} 

正如您从上面看到的,代码甚至不需要为应用程序调用segfault。

我使用Netbeans 6.7.1和GCC 4.3.2。

现在,我假设有链接的图书馆有问题,但我不知道是什么。我也链接到其他库(全部静态链接)。上面的类来自第一个链接库(至少在列表中是第一个)。如果我从第二个列出的库创建一个类的实例,一切运行良好。

这有可能是这个问题是相似的(或相关)到我的其他问题:https://stackoverflow.com/questions/1844190/linking-with-apache-xml-security-causes-unresolved-references

没有人有可能是什么问题,有什么建议?

回答

3

MyClass库内部可能存在一些静态初始化错误,如果您没有源代码,它将很难找到并修复。

+0

我有所有的源代码,所以如果确实如此,这应该不是问题。我会看一下。 – 2009-12-07 10:09:44

+0

Ahhhhhhhh。找到错误的代码;对swscanf的调用导致出错。 (我不知道代码有什么问题,但这是不同的时间。) – 2009-12-07 11:28:32

0

一个Stackoverflow。

MyClass可能会很大以适应堆栈。

+0

呃,好吗?我如何解决这个问题?尽管如此,我不太确定这是否是问题。如果我在同一个库中创建一个虚拟类并尝试引用它,我会得到相同的错误。 – 2009-12-07 10:03:05

+2

但他没有调用foobar,所以MyClass从未放在堆栈上 – 2009-12-07 10:03:13

+0

如果是这种情况,请声明一个指向MyClass的指针,并从堆中取出新的指针。如果这个问题解决了。 – rerun 2009-12-07 10:04:18

1

如果您正在Linux或OS X上开发,您可以通过在调试模式下编译并使用valgrind运行,获得更多有关此类错误的信息。

在调试模式下编译并不是绝对必要的,但会给出关于哪里出错和在哪里的更好的信息。

我也会在调试模式下编译包含MyClass的库。

另一件需要注意的事情是库编译时使用相同的编译器标志,因为在两种编译器设置下,静态对象具有不同的内部布局时会发生这种类型的崩溃。 (我花了很长时间在使用-DREENTRANT部分代码编译部分应用程序时进行跟踪,而不是在另一部分代码中,第三方组件在两种情况下以不同布局结束。)

+0

谢谢。使用Valgrind允许我在几秒钟内找出问题。 (如果可以的话,我也会将你的回答设置为答案。) – 2009-12-07 11:30:23

0

As far ,正如我从代码中了解到的,foobar永远不会被调用?只是声明它会导致段错误?

我可以想象,声明一个MyClass变量会导致一些模板实例化,它实现了一些静态初始化,失败。比如说,MyClass从SomeBase <&gt;派生,并且不可能在SomeBase <>中执行一些静态成员的初始化。当你删除MyClass变量的声明时,模板没有实例化,并且一切顺利......

class MyClass : public SomeBase<MyClass>{}; 

template<typename TYPE> 
class SomeBase<TYPE> { static CauseASegfault* m_casf; }; 

// some bad m_casf initialization here... 
+0

是的,代码永远不会被调用。另外,我是否声明了一个基本上为空的类的实例并不重要。 – 2009-12-07 11:06:22