2016-06-25 14 views
4

C++では、const int *をint *に変換できないことがわかりました。しかし、私はconst int *をint *に変換できるコードスニペットを持っています。私はC + +の初心者ですが、私はこれでgoogledしかし、私はちょうどconstのint * constの違反を避けるためにint *に変換することはできません言及リンクを持っている。それがエラーC++ const int *からint *への変換予期しない結果の処理

また
#include <iostream> 
using namespace std; 

int main(void) 
{ 
    const int a1 = 40; 
    const int* b1 = &a1; 
    int* c1 = (int *)(b1); 
    *c1 = 43; 
    cout<< c1<<" "<< &a1<<endl; 
    cout<< *c1<<" "<< a1<<endl; 
} 

せずにコンパイルされた理由を私は把握することはできませんよ、問題は、上記のプログラムの出力は次のとおりです。

0x7fff5476db8c 0x7fff5476db8c 
43 40 

誰かがC1整数ポインタが指している説明していただけますa1と同じアドレスですが、それぞれ異なる値43と40を持ちます。

+5

あなたは 'に'のconst T *を '鋳造得るものザッツT *' ... – tkausl

答えて

6

C++では、オブジェクトはconstであり、そうではありません。変更しようとする試みよりもconstの場合、未定義の動作が呼び出されます。それはあなたがしたことです。その時点で何かが起こる可能性があります。あなたが幸運なら、それはクラッシュします。運がよければ、コードが顧客の手元に届き、最大限の損害が発生するまで正常に動作します。

const int *をC++のint *に簡単に変換できます。あなたはちょうどしました。しかし、 "const int *"と "int *"は、指されるものがconstであるかどうかを意味するものではありません。これは、コンパイラが1つのケースで割り当てることを許可しないことを意味し、それ以外のケースでは割り当てることができます。 *c1constです。ポインタをint*にキャストしても、それがconstであるという事実は変わりません。未定義の動作。

+0

私は "あなたが簡単* intに*のconst int型に変換することができ、" 理解din't。どうやって?このコードを実行すると、 const int a = 40; int * b = &a1; エラーを返します: 'int *'型の変数を 'const int *'型のrvalueで初期化できません。また、出力がどのように異なっているかを説明してください40と43. – Mukesh

+0

他の回答とは異なる出力の理由があります。 – Mukesh

2

これは未定義の動作です。

しかし、この場合、constを意味するので、coutステートメントのa1ステートメントを実際の値40に置き換えることがコンパイラによって認識されています。

決してこれに頼ることはありません。それはあなたの猫を簡単に入れ墨することができます。

+0

いいえ、それはOPの猫に入れ墨できませんでした.. – Default

0

const int変数はスタック内のメモリを占有しますが、コンパイラはa1のインスタンスをすべて40に置き換えます。式&a1は置き換えられません。どういうわけかは魔法のようにがスタック上のメモリを指しています。内容を変更すると、メモリの内容は変更されますが、これらの定数は変更されません。40したがって、出力が異なります。

未定義の動作これはコンパイラによって異なる場合があります。 1つのコンパイラで43が表示され、別のコンパイラで常に40と表示され、クラッシュ(読み取り専用メモリへの書き込み)を引き起こすコードが生成されることがあります。しないでください!

+1

'const'がスタックにあるべき理由はありません。読み取り専用メモリを備えたマイクロプロセッサ用のコンパイラは、合法的にそこに置くことができる。例えば腕、avr。 –

+0

はい、理由はありません。しかしそれはそうです。 constのアドレスを、非const参照または非constポインタによって関数に渡してみてください。呼び出される関数はこれを変更して楽しむことができます。それが動作しない場合は、すべての場合に動作しません。 – Ajay

+0

@AndyBrown http://ideone.com/5MfBxP – Ajay

0

これを実行すると、おそらく役立ちます。

const int a1 = 40; 
std::cout<<"__________ const int a1 = 40; ____________________________________"<<std::endl; 
std::cout<<"a1: "<< a1<<std::endl; 
std::cout <<"&a1 "<< &a1<<std::endl; 
std::cout <<"*a1: INVALID"<<std::endl; 

const int* b1 = &a1; 
std::cout<<"__________ const int* b1 = &a1; ____________________________________"<<std::endl; 
std::cout<<"b1: "<< b1<<std::endl; 
std::cout <<"&b1 "<< &b1<<std::endl; 
std::cout <<"*b1 "<< *b1<<std::endl; 

int* c1 = (int *)(b1); 
std::cout<<"__________ int* c1 = (int *)(b1); ____________________________________"<<std::endl; 
std::cout<<"c1: "<< c1<<std::endl; 
std::cout <<"&c1 "<< &c1<<std::endl; 
std::cout <<"*c1 "<< *c1<<std::endl; 

*c1 = 43; 
std::cout<<"__________ *c1 = 43; ____________________________________"<<std::endl; 
std::cout<<"c1: "<< c1<<std::endl; 
std::cout <<"&c1 "<< &c1<<std::endl; 
std::cout <<"*c1 "<< *c1<<std::endl; 

std::cout<<"c1: "<< c1<<std::endl; 
std::cout<<"*c1: "<< *c1<<" -----> *&a1: "<< *&a1<<" - a1: "<< a1<<std::endl; 
std::cout<<"&c1: "<< &c1<<std::endl; 
+0

出力は(* c1 = 43の後にのみ): __________ * c1 = 43; ____________________________________ C1:0x7fff52857a7c &C1 0x7fff52857a68 * C1 43 C1:0x7fff52857a7c * C1:43 -----> *&A1:43 - A1:40 &C1:0x7fff52857a68 これは、コンパイラは、A1のすべてのインスタンスを置き換えている示唆。しかし、なぜconst変数を編集できるのですか? – Mukesh

+0

しかし、a1の値はまだ40ですが、メモリのどこかに値43があります。 私の実行中、* c1 = 43を割り当てる前に: '|名前|値|アドレス ' '| a1 | 40 | ff240' '| b1 | ff240 | ff238' '| c1 | ff240 | ff230' * c1 = 43の後、テーブルは私の出力で変わらない。 したがって、c1にまだa1のアドレスが含まれていれば、* c1は43になりますか? – iGian

関連する問題