2013-09-26 80 views
1

我創建了一個調用第三方代碼的C++/CLI包裝器,它發生在損壞的內存中。所以我懷疑也許代碼爲不是在C++法律在C++中這是合法的嗎?

下面是崩潰的代碼:試圖讀取或寫入保護內存 :

void Init_4bit_tab(unsigned char *dest,unsigned char *source) 
     { 
      unsigned char masque,i; 

      masque=0x08; 
      for(i=0; i<4; i++) { 
       dest[i] = (*source & masque)>>(3-i); 
       masque >>= 1; 
      } 
     } 

確切的錯誤了。這通常表明其他內存已損壞。

更新:

掃描第三方代碼後,這似乎是因爲它所傳遞的方式多維數組,但我仍然不知道是什麼導致了問題:

源功能

unsigned char Data_B[81]; 
... 
S_Box_Calc(&Data_B[33]); 

void S_Box_Calc(unsigned char *vect) 
     { 
       unsigned char *S_Box[8]; 
       unsigned lig,col,i; 

       S_Box[0]=S1; 
       S_Box[1]=S2; 
       S_Box[2]=S3; 
       S_Box[3]=S4; 
       S_Box[4]=S5; 
       S_Box[5]=S6; 
       S_Box[6]=S7; 
       S_Box[7]=S8; 

       for(i=0;i<8;i++) { 
        col= 8*vect[1+6*i] + 4*vect[2+6*i] + 2*vect[3+6*i] + vect[4+6*i]; 
        lig= 2*vect[6*i] + vect[5+6*i]; 
        Init_4bit_tab(&vect[4*i],&S_Box[i][col+lig*16]); 
       } 
     } 

更新2: 我檢查的數值上調試模式蒸餾水和源不爲空。然而,如果我試圖在此代碼dest [i] =(* source & masque)下快速觀看(* source & masque)>>(3-i);

我得到這個錯誤

(*源&面膜)錯誤: S1 ... Sn的最初定義的:&不能 '*源' 和 '假面舞會'

更新3進行該文件的全球範圍內,但我得到一個錯誤,當我把它原樣,所以我這樣初始化它們的構造:

unsigned char lS1[64] = { 
       14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7, 
       0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8, 
       4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0, 
       15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13 
      }; 
      std::copy(S1, S1 + 64, lS1); 

會這樣的問題呢?

+1

聽起來像'dest'所指向的內存無效/不夠大。 –

+1

source = nullptr也會導致崩潰 –

+0

什麼是「S1」,「S2」等的聲明/定義? – legends2k

回答

0

您顯示的代碼沒有問題,如果它通過了 有效的指針。如果它損壞內存,則可能是 ,因爲調用者未傳遞有效指針。

您的編輯後:如果S_Box_Calc被調用vect等於 Data_B + 33,爲您展示的範圍[vect, vect+48)是 法律,這意味着Init_4bit_tab不應該叫 用至44其實優異的價值,你顯示的代碼,它從來沒有被調用的值大於28,所以你不應該能夠 在這裏損壞內存。如果S1S8中的任何一個,但是,如果 沒有指向有效的記憶,您將會看到您陳述的症狀。

+0

截至編輯3,我試過看std :: copy後的構造函數,lSn沒有正確複製到Sn,而是它們全部變成了0xcd字符 – user2817517

0

這是完全合法的C++語法,編譯。檢查它的語義是否正確。您唯一可能無意中踏入UB地的地方是訪問dest指針,即它指向的數組距離它指向的地方應該至少有4個字符長。此外,由於錯誤說明訪問衝突,請確保dest指向可寫內存位置。

+0

我更新了我的代碼 – user2817517

+1

「Legal C++」!=「編譯C++」。 「未定義的行爲」是當你有一個非法程序不違反編譯器可以檢測到的任何規則時發生的情況。 –

+0

@SebastianRedl:從C++標準:在C++中,靜態或外部說明符只能應用於對象或函數的名稱。 將這些說明符與類型聲明一起使用在C++中是_illegal_,即編譯器會拋出錯誤。 – legends2k

0

你的溢出檢查在哪裏?您應該將大小傳遞給函數,以便在有可能溢出的情況下將寫入限制在內存中。它類似於strcpy()與strncpy()或strlcpy()在BSD中。也許如果你按照這些方法實現某些東西,並且在寫入的內存會溢出的情況下產生錯誤,你可能會發現內存損壞的原因。

相關問題