2012-08-08 80 views
2

当我出现内存访问错误时,我正在使用一些openFrameworks示例。在缩小问题一天之后,我有一个非常小的相对纯粹的C++代码样本,它仍然会导致内存访问错误。我会在这里发布整篇文章,因为它很短。这是一个g ++ bug,libc bug,还是我疯了(或者全部三个)?

有三个文件:testApp.cpp,main.cpp和testApp.h。

testApp.h:

#include <cstdlib> 
#include <iostream> 
#include <vector> 
#include <string> 
using namespace std; 
class X { 
public: 

    X(); 
    virtual ~X(); 

private: 

    vector<string> vertices; 
    vector<string> colors; 
    vector<string> normals; 
    vector<string> texCoords; 
    vector<string> indices; 
    bool bVertsChanged, bColorsChanged, bNormalsChanged, bTexCoordsChanged, bIndicesChanged; 
    int mode; 
    string name; 

    bool useColors; 
    bool useTextures; 
    bool useNormals; 
}; 

class testApp{ 

public: 
    void setup(); 

    X x1; 
    X x2; 
    vector<string> stroke; 
}; 

testApp.cpp:

#include "testApp.h" 

X::X() {} 
X::~X() {} 

void testApp::setup(){ 
    std::cout << stroke.size() << std::endl; 


} 

main.cpp中:

#define _GLIBCXX_DEBUG 
#include "testApp.h" 

int main(){ 

    testApp* o = new testApp(); 
    o->setup(); 
    std::cout << o->stroke.size() << std::endl; 

} 

编译,我打字:g++ -o testApp testApp.cpp main.cpp。 (我正在使用Ubuntu 12.04和stock g ++编译器版本4.6.3,x86_64架构)。当我运行它,我得到这个输出:

18446744073709025734 
0 

第一个数字来自调用testApp ::设置,打印出stroke.size()(这显然是不正确的)。第二个数字来自直接打印stroke.size()。似乎存在某种内存问题,但我不知道从哪里开始,或者在哪里提交错误。

这似乎只发生在testApp类完全像它那样指定的时候。如果你注释掉一个向量(或者甚至是一个bool),问题就会消失。如果您注释掉_GLIBCXX_DEBUG,该问题也会消失,但该标志应该是良性AFAIK。有什么建议?我应该在哪里提交错误?还是有什么明显的我忽略了?

另外,任何人都会介意在自己的计算机/编译器上试试这个,看看他们是否得到同样的问题?

+3

请注意,在标题中使用名称空间通常被认为是不好的做法。 – 2012-08-08 19:19:05

回答

5

_GLIBCXX_DEBUG可能会更改标准库容器的定义,因此您的程序违反了One Definition Rule (ODR)。在main.cpp翻译单元和testApp.cpp翻译单元中,X的定义不同,产生未定义的行为。

+1

+1这几乎肯定是问题所在。 – 2012-08-08 19:20:48

+0

感谢您的回答!所以你的意思是说X是不同的,因为它包含使用标准库的字段,这些标准库会由于'_GLIBCXX_DEBUG'发生微妙的变化? – noisecapella 2012-08-08 19:25:45

+0

这是我的猜测。如果是这样的话,您需要在所有翻译单元中一致地使用_GLIBCXX_DEBUG(可能通过在命令行或所有包含的头文件中定义它)。但这仅仅是基于经验的猜测:我不熟悉gcc或glibc,并且我找不到这个宏的任何文档。 – 2012-08-08 19:26:50