変数にメモリ内の必要なアドレスを割り当てることは可能ですか?
そうしようとしましたが、「割り当ての左オペランドとして左辺値が必要です」というエラーが表示されます。
int main() {
int i = 10;
&i = 7200;
printf("i=%d address=%u", i, &i);
}
私のアプローチの何が問題になっていますか?C で、必要なアドレスを変数に割り当てる方法はありますか?
変数にメモリ内の必要なアドレスを割り当てることは可能ですか?
そうしようとしましたが、「割り当ての左オペランドとして左辺値が必要です」というエラーが表示されます。
int main() {
int i = 10;
&i = 7200;
printf("i=%d address=%u", i, &i);
}
私のアプローチの何が問題になっていますか?C で、必要なアドレスを変数に割り当てる方法はありますか?
直接ではありません。ただし、これを行うことができます: int* i = 7200; .. そして i (つまり *i = 10) を使用しますが、クラッシュする可能性が高くなります。これは、低レベルの開発 (既知のメモリ アドレスを使用するデバイス ドライバーなど) を行う場合にのみ意味があります。
C言語では、特定のメモリアドレスに名前を「付ける」手段はありません。つまり、特定の変数名が特定のアドレスにある左辺値を参照することになっていることを言語に伝えることはできません。したがって、述べたように、あなたの質問に対する答えは「いいえ」です。物語の終わり。
さらに、正式に言えば、Cで特定の数値アドレスを操作するための代替のポータブルな方法はありません。言語自体は、それを行うのに役立つ機能を定義していません。
ただし、特定の実装では、特定のアドレスにアクセスする手段が提供される場合があります。一般的な実装では、整数値A
をポインター型に変換すると、アドレスを指すポインターが作成されますA
。そのようなポインタを逆参照することにより、そのメモリ位置にアクセスできます。
最新のオペレーティングシステムでx86タイプのプロセッサを使用していると仮定すると、メモリの場所に書き込むことはできません。CPUはOSと連携してメモリを保護し、あるプロセスが誤って(または意図的に)別のプロセスのメモリを上書きしないようにします。これを許可すると、セキュリティ上のリスクが発生します(バッファオーバーフローを参照)。とにかくしようとすると、OS / CPUがこれを行うことができないため、「セグメンテーション違反」エラーが発生します。
これに関する技術的な詳細については、1、2、および3から始めます。
代わりに、を使用して書き込み可能なメモリ位置を指定するようにOSに要求しますmalloc
。この場合、OSカーネル(通常、任意のメモリ位置への書き込みが許可されている唯一のプロセス)は、メモリの空き領域を見つけて、それをプロセスに割り当てます。割り当てプロセスは、メモリのその領域をプロセスに属するものとしてマークし、読み取りと書き込みができるようにします。
ただし、OS /プロセッサのアーキテクチャ/構成が異なると、任意の場所に書き込むことができます。その場合、このコードは機能します。
#include <stdio.h>
void main() {
int *ptr;
ptr = (int*)7000;
*ptr = 10;
printf("Value: %i", *ptr);
}
ポータブルではありません。ただし、一部のコンパイラ (通常は組み込みの世界向け) には、それを行うための拡張機能があります。
たとえば、IAR コンパイラ (ここでは MSP430 用) では、次のように実行できます。
static const char version[] @ 0x1000 = "v1.0";
これにより、オブジェクトversion
がメモリ アドレスに配置されます0x1000
。
&aの「&」はコンパイル時にiのアドレスを評価しますが、これは仮想アドレスだと思います。したがって、コンパイラによると、これは左辺値ではありません。代わりにポインタを使用してください
それは不可能です。コンパイラの拡張機能で可能かもしれません。ただし、必要なアドレスでメモリにアクセスできます (アドレスがプロセスにアクセスできる場合)。
int addr = 7200;
*((int*)addr) = newVal;
いいえ。
できたとしても、7200 はポインター (メモリ アドレス) ではなく、int であるため、とにかく機能しません。
変数が持つアドレスを特定する方法はおそらくありません。しかし、最後の希望として、「ポインター」と呼ばれるものがあり、アドレスの値を変更できます7200
(ただし、このアドレスにはおそらくアクセスできません)。
int *i = (int *)7200;
*i = 10;
ldscript/linker コマンド ファイルを使用します。ただし、これは実行時ではなくリンク時に割り当てられます。
リンカ コマンド ファイルの構文は、特定のコンパイラに大きく依存します。そのため、コンパイラのリンカー コマンド ファイルをグーグルで検索する必要があります。
おおよその疑似構文は次のようになります。
In linker command file:
.section start=0x1000 lenth=0x100 myVariables
In C file:
#pragma section myVariables
int myVar=10;