2009-03-07 16 views
2

Cでは、その関数を呼び出す側(読み取り側)のメモリを、その関数を呼び出す側の読み取り専用レベルより低いレベルで「管理」することができます。 return * constは有効ではありませんが、私はプログラミングティックを見落としていたのかどうか疑問に思いましたか?メモリを読み取り専用で公開する

ありがとうございました。

const uint8_t * get_value(int index) 
{ 
static uint8_t data[2] = {0, 0}; 
return (const uint8_t *)&data[index]; 
} 

int main(void) 
{ 
uint8_t * value; 
value = get_value(1); 

*value += 1; 
return 0; 
} 

@j_random_hackerは、余分なバリアが、私はそのデータのカジュアルな誤使用を防ぐために探していることを示します私の質問への良好な妥協を推奨。

typedef struct 
{ 
    const uint8_t * value; 
    const uint8_t size; 

} readonly_t; 

readonly_t get_value(int index, int size) 
{ 
    static uint8_t data[2] = {0, 0}; 
    uint8_t rsize; 

    /* ... validate index, size params */ 

    readonly_t r = { &data[index], rsize }; 
    return r; 
} 
+0

なぜこれがコミュニティのwikiであるのかわかりません。 – TheTXI

+0

私の間違い。ここを少しクリックするだけで、すばやく簡単に送信してから送信できますが、元に戻すことはできません。 – Oliver

答えて

6

それはCです!あなたはすることはできません:)常にそれを回避する方法があります。ただそれをconstにして、誰かがそれを変更しないことを願ってください。

アドインなどをホストする場合は、メモリへのアクセスを制限するために、別のプロセスで実行する必要があります。

+0

あなたは技術的に正しいと言えるので、このシナリオでは私は本当の読み取り専用機能を達成できません。あなたの入力をありがとう – Oliver

1
+0

プラットフォームに依存し、割り当て粒度> = 4KB。しかし、それは問題ではない場合:) :) – peterchen

+0

それから遠いMSプラットフォームでは、作業していません。 OSEK OSとバニラCを使用していますが、標準ライブラリはありません。 – Oliver

+0

ええ、そのような骨の折れる答えです。しかし、私は他の人がC言語ではその不可能を指摘していると考えました。もちろん、呼び出し元は常にVirtualProtect()を使って状態を変更することができます。もっとも良いことは、ある種のハンドルを返し、それを内部的に不透明なデータ構造にマップすることです。 –

1

は、のように、オブジェクトの値に尖ったを返し、ポインタを返さないでください:

uint8_t get_value(int index) 
{ 
    static uint8_t data[2] = {0, 0}; 
    return data[index]; 
} 
+0

これは、nバイトの長さ(例:構造) – Oliver

+0

です。次に、あなたがすでに持っているものがこの言語でできる最高のものです。 – dirkgently

+0

nが固定されている場合は、構造体に配列をラップし、その値を返すことができます。 Cでは構造体をファーストクラスの値として扱うことができます(何らかの理由で配列には=、代入、返すことができます)。 –

0

メモリ保護は、「Cにおける言語構造ではありません、ハードウェアとは何かです。例えば、ポインタが指すメモリがあるROM領域などにある場合、書き込みは不可能です。また、ハードウェアレベルでReadOnlyの部分を作成することもできますし、メモリの例外がいくつか予想されます。

関連する問題