2017-04-18 28 views
0

我必須整合來自tetgen(網格生成器)的代碼,這顯然是經常使用的代碼。但是,我必須使用舊版本(1.4.3而不是1.5),這給我一個'寫入訪問衝突'。 相關的功能是在這裏:爲什麼會將指針從double ***轉換爲double **以寫入訪問衝突?

void tetgenmesh::dummyinit(int tetwords, int shwords) 
{ 
    unsigned long alignptr; 

    // Set up 'dummytet', the 'tetrahedron' that occupies "outer space". 
    dummytetbase = (tetrahedron *) new char[tetwords * sizeof(tetrahedron) 
              + tetrahedrons->alignbytes]; 
    // Align 'dummytet' on a 'tetrahedrons->alignbytes'-byte boundary. 
    alignptr = (unsigned long) dummytetbase; 
    dummytet = (tetrahedron *) 
    (alignptr + (unsigned long) tetrahedrons->alignbytes 
    - (alignptr % (unsigned long) tetrahedrons->alignbytes)); 
    // Initialize the four adjoining tetrahedra to be "outer space". These 
    // will eventually be changed by various bonding operations, but their 
    // values don't really matter, as long as they can legally be 
    // dereferenced. 
    dummytet[0] = (tetrahedron) dummytet; 
    dummytet[1] = (tetrahedron) dummytet; 
    dummytet[2] = (tetrahedron) dummytet; 
    dummytet[3] = (tetrahedron) dummytet; 
... 
... 
... 
} 

「dummytetbase」和「dummytet」都是雙***球,四面體是雙**指針。

示例值包括:

'tetwords' 是:12.

'(無符號長整數)tetrahedrons-> alignbytes':8.

「tetwords *的sizeof(四面體)+ tetrahedrons- > alignbytes'是:104

'(alignptr%(無符號長整數)tetrahedrons-> alignbytes)' 是:0.

代碼編譯很好,但是當指針CAS從'dummytet'到'dummytet [0]'應該完成,我得到這個'寫訪問衝突'。

因此,dummytet獲得dummytetbase + 8的地址。而且dummytet [x]獲得所有相同的地址,但這會導致寫入違規。

任何想法爲什麼發生這種情況? 謝謝!

+0

這是tetgen的原始代碼。我沒有改變一個單詞... – sciloop

+0

我用'uint32_t'替換了'unsigned long',但是寫入訪問衝突仍然存在... – sciloop

+0

很難真正地說出未經調試的情況。也許試圖找出誰來維護圖書館的電子郵件。 – AndyG

回答

0

簡單:double***double**是完全不同的類型。 double***指向double**,而double**指向double*。遞歸地應用這個邏輯。

現在既然都是指針,編譯器將使用32位或64位。你可以告訴編譯器閉嘴,拋開差異,並且在編譯時忽略這個問題。這意味着您的編譯時問題現在有運行時症狀。

退一步:如果您有一個T* ptr並且需要一個T值,您不寫(T) ptr。你寫*ptrptr[5],或類似的東西。這仍然成立時T==double**

+0

是的,我明白你的意思。但是這意味着tetgen代碼有內置錯誤......這個版本已經有7年了,已經找到了幾個程序的方法......到目前爲止還沒有人抱怨過?所以,你說,這種使用相應雙***指針的地址來初始化雙**指針的技術通常是無效的,對吧?如果我現在看,那對我來說也是合理的。 – sciloop

+0

@sciloop:編譯器*令人難以置信地*挑剔,所以我將成爲一樣。 「用**對應的雙***指針的地址初始化'雙**'指針是另一個問題。 「雙***」的地址是「雙****」。這是4星級,以及我們以前在這個問題中沒有看到的類型。你不能用'double ***'或'double ****'初始化'double **'。 – MSalters

+0

啊,對不起,雙***的地址......那麼,如果那是不可能的,那麼tetgen創造者的意圖是什麼。如果我正確地理解了代碼,那麼沒有爲double **指針保留內存,對吧?這是否意味着代碼通常不起作用? – sciloop