2012-08-08 82 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