2017-07-21 15 views
-1

ポインタの値は0x0224のようなメモリアドレスなので、何らかの形でポインタにリテラルとして与えられたアドレスを割り当てることができますか?私はポインタに整数のリテラルを割り当てることで試しましたが、それはおそらくあなたが推測することができるように、うまくいかなかったのです。アドレスをリテラルとしてポインタに割り当てますか?

+2

'some_type * some_name = 1234;'の実行方法を聞いていますか? – NathanOliver

+0

達成しようとしていることの例を挙げることはできますか? 'Object * obj = reinterpret_cast (0x0224)'のようなもの? –

+0

あなたは、ある値の*割り当ての仕組みに興味がありますか*割り当てられている*値そのものに興味がありますか?好奇心は前者に答え、私は後者に答えます。 – Patrick87

答えて

2

あなたは絶対にあなたの心のコンテンツにこれを行うことができ、簡単なreinterpret_cast

auto ptr = reinterpret_cast<void*>(0x123); 
+0

ああ大丈夫、それは私が行っていたものです、ありがとうございます。しかし、なぜそれが働くためには/キャストを使う必要がありますか?それはリテラルを住所として扱うためですか?そして、これはあなたが思うように動作しますか?あなたの例のように、 'ptr'はアドレス' 0x123'に割り当てられますか? –

+0

そのフォームのリテラルが 'int'型で、' int'が 'reinterpret_cast'なしで' void * 'に変換できないため、キャストが必要です。これはあなたが「はい」と考えるように機能します。負の整数などを使うときは注意してください。 – Curious

+0

ああは意味があります。しかし、なぜC-castやstatic_castを使用しないのですか? –

0

でこれを行うことができます。プロセスのメモリ空間を分離するオペレーティングシステムは、通常、プロセスの割り当てられたメモリ空間外のメモリにアクセスしようとするとプログラムを終了させますが、割り当てられている値がプロセスにアクセスできるものであれば、読み書きすることができます(いくつかの追加制限の対象となる可能性があります)。

コメントで指摘されているように、この質問は実際にそのような割り当てを実行しているのを参照することもできます。これは他の回答でもよくカバーされています。簡単な答えは、リテラルを適切な型のポインタ値にキャストする必要があるということです。

+0

この回答は参考になりましたが、これを達成するための*方法*については触れていません。 –

+0

@FrançoisAndrieux他の回答を見る私は質問の他の解釈を見ていると思います。*どういうわけか*割り当ての実際の仕組みを参照してください。代わりに*何らかの*を*リテラル*に付けました。私はこの回答を残しておきます。他の添付ファイルは他の場所でもよくカバーされています。これはリテラルを選択する* how *についてのガイダンスを提供します。コンパイラが文句を言うとキャストしようとするのが自然であろうと思うし、初心者がやってみたい最初のことはうまくいくので、これは私の解釈だと思う。 – Patrick87

0

ポインタの値がメモリアドレスであるので、0x0224のように、あなたは何とかポインタにリテラルとして指定されたアドレスを割り当てる ことができますか?

あなたのデスクトップの答えは「いいえ」と思います。

ユーザープロセス内のポインタの値は、仮想メモリアドレスです。アドレスは事実上存在し、物理メモリにマッピングされていますが、実際のアドレスは明らかではありません。特に、物理はアプリケーションの実行ごとに異なる可能性があります。

したがって、問題は、繰り返し可能なリテラルを作成する特定のアドレスをコンパイル時に使用する方法を発見する方法です。次回の実行時にどのような(仮想の)メモリにアクセスできるかをどのようにして知ることができますか?

私のデスクトップでは、私はできないと思います。


このように、テレコム業界での私の組み込みシステムの例を紹介します。私はあなたのコードが物理メモリにマップされたデバイスへのアクセス権を持っているときに、あなたの質問が示唆していることがわかると思います。

ここではmcuと呼ばれる棚のコンピュータレベルまでスキップします。

mcuには複数のロジックデバイスがあります。我々は、ランダムにPCI2(私が最初に見つかったもの)

class mcu_pci2_t // all reg's 32 bit 
{ 
    public: 
    mcu_pci2_t(void){}; 
    ~mcu_pci2_t(void){/*always implement*/}; 

    enum MCU_PCI2_CONSTRAINTS 
    {   
    MCU_PCI2_ADDR  = 0x80000000LU,     // 0x8000 0000 
    // 
    ... 
    // 
    MC_SRBL_FPGA_ADDR = MCU_PCI2_ADDR + 0x08000000LU, // 0x8800 0000 
    // 
    MC_PCI2_CONSTRAINTS_END 
    }; 

次を検査することを選択し、このスニペットでは、我々はMC_SRBL_FPGA_ADDRを詳しく見ていきます。 mcu上のハードウェアロジックはアドレス0x8000,0000LUから開始し、SRBLは0x8800,0000から開始します。これらのエントリの多くも削除しました。

enum MC_SRBL_CONSTRAINTS 
{ 
    CRXX_LED_ADDR   = MC_SRBL_FPGA_ADDR + 0x00000004, // 0x8100 0004 red,off  Bit0 
... 
    // 
    FAN_LMPTEST_ADDR   = MC_SRBL_FPGA_ADDR + 0x00000040, // 0x8800 0040 normal/test Bit0 
    // 
... 
// 

ここで、コードがFAN_LMPTEST_ADDRをどのように使用するかを説明します。ここで

class fan_lmptest_t 
{ 
public: 
    fan_lmptest_t(void){}; 
    ~fan_lmptest_t(void){/*always implement*/}; 

    // returns 0 when successful 
    const char* change(bool on, bool sim=false); 

    uint32_t value(void) { uint32_t ret_val = reg(); return(ret_val); }; 

private: 
    inline vuint32_t& reg(void) { 
     return(*(reinterpret_cast<vuint32_t*>(FAN_LMPTEST_ADDR))); 
    }; 

private: // coding standard: when not used, make NOT accessible AND do NOT implement 
    fan_lmptest_t(const fan_lmptest_t&);   // copy constructor X(const X&) 
    fan_lmptest_t& operator= (const fan_lmptest_t&);// copy assignment  X& operator= (const X&) 
}; 

我々は列挙型の物理アドレスの値がこの場合

reinterpret_cast<vuint32_t*>(FAN_LMPTEST_ADDR); 

ポインタにキャストされていることが分かり、vuint32_tは、コンパイラが、「揮発性のuint32_t」として、このアドレスのデータを扱うように命令されることを意味。

(FYI - 変化()メソッドが他の.ccファイルに実装されている)

操作上、lamptestこのコードからかなりの距離であり、活性化または非活性化することを決定するユーザ・インタフェース・コード。それは、完全なファンをオンまたはオフにすることです。明らかに、ファンはランプテストの一部です。大丈夫だよー。

これはあなたの質問に非常によく似ています。リテラル(つまり列挙型)を物理アドレスにキャストし、アドレスがハードウェアに正しくマップされていれば、ユーレカ!我々はファンを持っています。


FYI - その組み込みオペレーティングシステムはONEAによってOSEです。 mcuはいくつかのppcの派生物に基づいていますが、どちらが覚えていないのですか?ハードウェアにマップされたメモリは専用の32ビット幅のhwバスを使用しますが、コードとスタックとヒープはDRAMメモリにあり、合理的なキャッシュと64ビット幅のバスがあります。

関連する問題