2011-06-12 113 views
0

我一直在嘗試解決程序中用於限制卷層次結構的訪問衝突。運行時出現訪問衝突錯誤。我已經使用了SDL和lib3d軟件包。C++中的訪問衝突錯誤

Error: Unhandled exception at 0x00fa2e80 in bvh.exe: 0xC0000005: Access violation reading location 0x00000004.

調用堆棧:>bvh.exe!Triangle::Triangle(const Vertex * vertexA, const Vertex * vertexB, const Vertex * vertexC, unsigned int r, unsigned int g, unsigned int b, bool twosided, bool triNormalProvided, Float3 triNormal)線393 +量0x150字節C++

我在下面的方式定義我的結構:

struct Float3 
{ 
    float X, Y Z; 
    Float3(float x=0, float y=0, float z=0) 
     : 
    X(x), Y(y), Z(z){} 

    Float3(const Float3& rhs) 
     : 
    X(rhs.X), Y(rhs.Y), Z(rhs.Z){} 

    inline Float3& operator+=(const Float3& rhs) 
    { 
    X += rhs.X; Y += rhs.Y; Z += rhs.Z; return *this; 
    } 

    // similar for the other operators 

    void assignSmaller(const Float3& rhs) 
    { 
     X = min(X, rhs.X); 
     Y = min(Y, rhs.Y); 
     Z = min(Z, rhs.Z); 
    } 

    void assignBigger(const Float3& rhs) 
     { 
     X = max(X, rhs.X); 
     Y = max(Y, rhs.Y); 
     Z = max(Z, rhs.Z); 
     } 

    float length() 
    { 
    return sqrt(X*X +Y*Y + Z*Z); 
    } 

    inline float lengthsq() 
    { 
    return X*X +Y*Y + Z*Z; 
    } 

    inline void Normalize() 
    { 
    float norm = length(); 
    X/= norm; Y/= norm; Z/= norm; 
    } 
}; 

struct Vertex : public Float3 
{ 
    Float3 n; 
    unsigned _ambientOcclusionCoeff; 

    Vertex(float x, float y, float z, float nx, float ny, float nz, unsigned char amb=60) 
    : 
    Float3(x,y,z), n(nx,ny,nz), _ambientOcclusionCoeff(amb){} 

}; 

struct Pixel { 
    float _b, _g, _r; 
    Pixel(float r=0.f, float g=0.f, float b=0.f) 
    : 
    _b(b), _g(g), _r(r) {} 

Pixel& operator+=(const Pixel& rhs) { _b += rhs._b; _g += rhs._g; _r += rhs._r; return *this; } 
    // similar for the other operators 

}; 

struct Triangle 
{ 
    const Vertex *_vertexA, *_vertexB, *_vertexC; 
    Float3 centroid, n; 
    // Color: 
    Pixel _colorf; 
    // precomputed for SDL surface 
    Uint32 _color; 

    // Should we backface cull this triangle? 
    bool _twoSided; 

    // Raytracing intersection pre-computed cache: 
    float _d, _d1, _d2, _d3; 
    Float3 _e1, _e2, _e3, _bottom, _top; 

    Triangle(
    const Vertex *vertexA, 
     const Vertex *vertexB, 
    const Vertex *vertexC, 
    unsigned r, unsigned g, unsigned b, 
    bool twosided = false, bool triNormalProvided=false, 
    Float3 triNormal=Float3(0.0f,0.0f,0.0f)) 
    : 

    _vertexA(vertexA), _vertexB(vertexB), _vertexC(vertexC), 

    centroid((vertexA->X + vertexB->X + vertexC->X)/3.0f, 
     (vertexA->Y + vertexB->Y + vertexC->Y)/3.0f, 
     (vertexA->Z + vertexB->Z + vertexC->Z)/3.0f), 

    _colorf((float)r,(float)g,(float)b), // For use in all other cases 
    _color(SDL_MapRGB(Screen::_surface->format, r,g,b)), // For use with DrawPixel 

    _twoSided(twosided), 

    _bottom(FLT_MAX,FLT_MAX, FLT_MAX), // Will be updated after centering in Loader 
    _top(-FLT_MAX, -FLT_MAX,-FLT_MAX) // Will be updated after centering in Loader 
    { 
     // this is where the debugger points to with an access violation error. 
     if (!triNormalProvided) 
     { 
     n = Float3((vertexA->n.X + vertexB->n.X + vertexC->n.X)/3.0f, 
       (vertexA->n.Y + vertexB->n.Y + vertexC->n.Y)/3.0f, 
       (vertexA->n.Z + vertexB->n.Z + vertexC->n.Z)/3.0f); 
     n.Normalize(); 
     } 
     else {n = triNormal;} 
     } 
}; 
+1

如果你想要真正的幫助,需要一些代碼 – 2011-06-12 19:17:44

+1

是的。您禁用編譯並且不運行該程序。 – alternative 2011-06-12 19:21:06

+0

而不是問如何讓環境忽略你的錯誤發佈一些代碼片段來識別問題,並詢問我們如何修復錯誤......只是一個想法:P – AJG85 2011-06-12 19:24:34

回答

8

你不 「避免訪問衝突錯誤」 通過更改IDE中的設置。

您通過修復代碼來解決這些故障。您在某處破壞內存,解除引用無效指針,在緩衝區末尾寫入/讀取,free已釋放的內存......

+1

你的兩個建議是不正確的,它不能寫入超過緩衝區末端(它的這麼低的#),它可以根據我對這種情況的瞭解,我不會釋放free內存(我沒有看到有任何理由嘗試訪問'4',它幾乎決不會正確解除引用) – alternative 2011-06-12 19:37:53

+0

@mathepic:It是一個關於訪問衝突的一般性評論 – 2011-06-12 19:59:13

3

看起來您試圖訪問第二個成員變量該成員函數中的三角形,而指針this爲NULL。

或者,也許一旦傳入的頂點指針爲NULL。

舉個例子,這將產生你所看到的錯誤:

struct Foo 
{ 
    void bar() { cout << b << end; } 
    int a, b; 
}; 

int main() 
{ 
    Foo* f = 0; 
    f->bar(); 
    return 0; 
} 

b訪問在bar()會實際上是一個int訪問由4sizeof(int))偏移this。如果thisNULL(如示例中所示),那麼您將在位置0x00000004處發生訪問衝突。

確保所有的指針都是有效的。

+0

頂點的值來自一個文件,我確信它沒有任何NULL值 – user793337 2011-06-12 19:41:41

+1

@user:不是NULL值,NULL指針在代碼中的某處你必須是創建'Vertex'和'Triangle'對象並調用它們的函數,在某些時候,你可能用一個尚未初始化的指針調用函數。 – 2011-06-12 19:43:29

4

我嚴重懷疑0x00000004指向的東西。通常這樣的數字不會;他們太「正常」了。你不能取消引用int