Google で多くの調査を行った後、次のプログラムを見つけました。
#include <stdio.h>
int main()
{
int val;
char *a = (char*) 0x1000;
*a = 20;
val = *a;
printf("%d", val);
}
しかし、で実行時エラーをスローしています*a = 20
。
では、特定のメモリ位置を読み書きするにはどうすればよいでしょうか?
Google で多くの調査を行った後、次のプログラムを見つけました。
#include <stdio.h>
int main()
{
int val;
char *a = (char*) 0x1000;
*a = 20;
val = *a;
printf("%d", val);
}
しかし、で実行時エラーをスローしています*a = 20
。
では、特定のメモリ位置を読み書きするにはどうすればよいでしょうか?
システムを除いて、このメモリに書き込むことができず、セグメンテーション違反が発生します。
セグメンテーション違反 (多くの場合、segfault と短縮されます)、バス エラー、またはアクセス違反は、通常、CPU が物理的にアドレス指定できないメモリにアクセスしようとする試みです。これは、ハードウェアがメモリ アクセス違反についてオペレーティング システムに通知したときに発生します。次に、OS カーネルは、例外の原因となったプロセスにシグナルを送信します。デフォルトでは、シグナルを受信したプロセスはコアをダンプして終了します。デフォルトのシグナルハンドラをオーバーライドして、シグナルの処理方法をカスタマイズすることもできます。
詳しく知りたい場合は、ウィキペディアで MMU を調べてください。
ヒープから合法的にメモリを要求する方法は次のとおりです。このmalloc()
関数は、割り当てるバイト数をパラメーターとして受け取ります。every は、使用が終わった後、同じメモリへmalloc()
の呼び出しによって一致する必要があることに注意してください。free()
呼び出しは通常、free()
呼び出した場所と同じ関数内にある必要がありますmalloc()
。
#include <stdio.h>
int main()
{
int val;
char *a;
a = (char*)malloc(sizeof(char) * 1);
*a = 20;
val = (int)*a;
printf("%d", val);
free(a);
return 0;
}
次のような非常に簡単な方法で、スタックにメモリを割り当てることもできます。
#include <stdio.h>
int main()
{
int val;
char *a;
char b;
a = &b;
*a = 20;
val = (int)*a;
printf("%d", val);
return 0;
}
そのアドレスに何が入れられているかわからないため、これはセグメント違反(SEGFAULT)をスローします。ほとんどの場合、それはカーネルスペースであり、ホスティング環境では、別のアプリケーションのメモリに意地悪に書き込むことを望んでいません。プログラムがアクセスできることを知っているメモリにのみ書き込む必要があります。そうしないと、実行時に不可解なクラッシュが発生します。
コードをユーザースペース(現在のユーザースペース)で実行している場合、取得するすべてのアドレスは仮想アドレスであり、物理アドレスではありません。仮想アドレスを想定して書き込むことはできません。
実際、仮想メモリモデルでは、アドレスを有効なアドレスと見なすことはできません。有効なアドレスをコンパイラの実装に返すのはメモリマネージャの責任であり、コンパイラの実装はそれをユーザープログラムに処理しますが、その逆はありません。
プログラムがアドレスに書き込めるようにするには:
ランダムなアドレスに書き込むことはできません。プログラムが書き込めるメモリの内容のみを変更できます。
いくつかの変数の内容を変更する必要がある場合、それがポインタが対象である理由です。
char a = 'x';
char* ptr = &a; // stored at some 0x....
*ptr = 'b'; // you just wrote at 0x....
許可の問題、OS はメモリ空間をランダム アクセスから保護します。
正確なエラーを指定していませんがsegmentation fault
、メモリ アクセス違反を明確に示す " " が表示されていると思います。
特定のメモリ位置に書き込むことができます。
ただし、その場所に書き込む権限がある場合に限ります。
あなたが得ているのは、あなたが書くことを禁じているオペレーティングシステムです0x1000
。
これは、メモリ位置 0x1000 にデータを書き込む正しい方法です。しかし、この仮想メモリの時代では、書き込む実際のメモリの場所を事前に知ることはほとんどないため、この種のものは使用されません。
これで解決しようとしている実際の問題を教えていただければ、私たちがお手伝いできるかもしれません。
メモリの場所をランダムに選択して書き込むことはできません。メモリの場所はユーザーに割り当てられ、書き込み可能である必要があります。
一般的に言えば、変数の参照/アドレスを取得し、&
それにデータを書き込むことができます。または、malloc() を使用して、ヒープにデータを書き込むスペースを要求できます。
この回答は、メモリ上でデータを読み書きする方法のみをカバーしています。ただし、プログラムが正常に機能するように、正しい方法で行う方法については説明しません。他の答えはおそらくこれを私のものよりもよくカバーしています。
まず、書き込みたいメモリの場所を確認する必要があります。次に、書き込み権限があるかどうかを確認します。