2014-09-02 88 views
2
限制訪問陣列

重新表述的問題更清楚:通過索引錯誤

我有興趣加入規則Coverity的跳棋和想諮詢下,如果它是可行的,什麼是需要做來實現。 我在談論C編程,我想限制使用定義的枚舉器訪問數組 - 而不是任何int索引。

例如,我有2個陣列,橘子和蘋果的大小5和10個相應的單元格。

爲了避免濫用數組,我想定義2枚枚舉(或者typedefs,如果需要的話),一個用於桔子,一個用於蘋果。

Enum apples { 
    A0 = 0, 
    A1 = 1, 
    A2 = 2, 
    A3 = 3, 
    A4 = 4, 
} 

Enum oranges { 
    O0 = 0, 
    O1 = 1, 
    O2 = 2, 
    O3 = 3, 
    O4 = 4, 
    O5 = 5, 
    O6 = 6, 
    O7 = 7, 
    O8 = 8, 
    O9 = 9, 
} 

我想添加一個規則來檢查對這些數組的訪問權限。 例如:

Apples[A4]; //success 

Apples[O0]; // coverity error 

Apples[2]; // coverity error 

是否可以添加這樣的規則?

+4

您的信息'C'不檢查數組索引的界限。 – 2014-09-02 11:50:10

+0

我知道,如果需要,我可以在保險範圍內進行檢查。 關於帶外,它是無損檢查掩護。 – 2014-09-02 11:50:50

+1

@Jayesh:事實上,由於這個原因,開發/質量保證/支持費用被浪費了,因爲這可能無疑會資助幾項載人火星飛行任務,包括返程旅行;) – 2014-09-02 13:27:43

回答

0

如果知道長度,你可以做一個函數來檢查這個。我沒有看到另一個解決方案,因爲C沒有檢出索引。

<array_type> accessArray(<array_type> array, int index, int len) 
{ 
    if (index > len || index < 0) { 
     return <error_value>; // return an error value set by you 
    } else { 
     return array[index]; 
    } 
} 
+0

您是否區分零如何表示錯誤和0表示正常值? – BLUEPIXY 2014-09-02 12:04:55

+0

是的,觀察得很好。謝謝。 – 2014-09-02 12:11:56

+1

這隻會檢查我已經有了覆蓋範圍的邊界,我想添加更多的規則來掩蓋相反的情況。 – 2014-09-02 13:27:54

0

//使用模運算以避免內的束縛

#include <stdio.h> 
#define LIMIT 5 
int main() 
{ 

     char array[LIMIT] = {'A', 'B', 'C', 'D', 'E'}; 
     for(int i = 0; i < LIMIT + 3; i++) 
       printf("ELEMENT = '%c'\n", array[i%LIMIT]); 

     return 0; 
} 
0

要做到這樣的事情純C(而不是使用外部工具),你可以使用結構,而不是枚舉代表您允許的指數範圍。結構是強類型的,因此類型系統將阻止您使用用於一個數組的索引器訪問另一個數組。

有幾種方法可以解決這個問題 - 您可以將int索引放入結構中,或者(假設元素範圍是連續的),您可以通過直接使用結構身份而不是任何暴露的整數都:

typedef struct { int UNUSED; } appleI; 
typedef struct { int UNUSED; } orangeI; 

const appleI apples[5] = { }; 

const orangeI oranges[10] = { }; 

apple_t * Apples(appleI * i) { //The actual array is hidden from view 
    static apple_t _Apples[] = { ... }; 
    return &_Apples[i - &apples[0]]; 
} 

orange_t * Oranges(orangeI * i) { 
    static orange_t _Oranges[] = { ... }; 
    return &_Oranges[i - &oranges[0]]; 
} 

#define A0 (&apples[0]) 
#define A1 (&apples[1]) 
// ...etc 

... 
orange_t myOrange = ...; 
*Oranges(O2) = myOrange; 
apple_t myApple = *Apples(A3); 
  • 可以潛在地添加了一系列檢查的「陣列」功能中,以確保索引類型沒有新的實例使用(這肯定會是一個錯誤 - 這些類型對用戶代碼應該是不透明的)

  • 你仍然可以使用A0 + 1

  • 這東西應該是相當容易的一個功能強大的編譯器內聯和向下降低到什麼

+0

感謝您的建議,它看起來不錯。 但是我有陣列已經定義的問題,我不能改變他們的定義。 另外我正在談論一個有超過1人開發的FW,所以我想直接使用數組/索引,但有能力捕捉任何濫用,即使使用外部工具如覆蓋。 – 2014-09-03 18:57:50