同一アドレスが、異なる値を指している?

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
inemaru
記事: 108
登録日時: 7年前

同一アドレスが、異なる値を指している?

#1

投稿記事 by inemaru » 7年前

お世話になります。
C++における、const変数の挙動について解せない事があったので質問しました。

アドレスの値を変数に格納後、
格納した変数を使用してアドレスの指す変数を書き換えるといった方法で
const なデータの書き換えを行った際、
同一のアドレスが指す内容が変化する動作についてです。

プログラム中で、変数がどのようになっているのか分からず困っています。
書き換えられたデータは、どのように元の数値を保っているのでしょうか?
(ソースコード中では、dataが書き換え後も120として扱われている挙動)

constなデータの書き換えが目的ではないので、
const装飾子は、本来書き換えられては困るインスタンスに使用し、
外す必要がある場合は、const_castを使用するものと理解した上での質問です。

以上、よろしくお願い致します。

知識量:
  C++11の入門書を読み終えた程度
OS:
  Windows10 Pro
確認環境:
  ・Visual Studio Professional 2013
  ・Clang 3.8 / LLVM 3.8

コード:

/*
*	const なデータをアドレス経由で書き換える実験
*	同じアドレスなのに、アクセス方法によって値が異なる現象
*/
#include <iostream>

int main()
{
	using namespace std;

	// 元になるconst変数
	const int data = 120;

	// アドレスを変数に落とす
	intptr_t address = reinterpret_cast<intptr_t>(&data);

	// アドレスを使用して内容を書き換える
	(*reinterpret_cast<int*>(address)) = 100;

	// 念のため両者のアドレスが一致するか確認する
	if (&(*reinterpret_cast<int*>(address)) == &data)
	{
		// 表示してみる
		cout << "アドレス一致" << endl;
		cout << "アドレス:" << &(*reinterpret_cast<int*>(address))
			<< "\t値:" << (*reinterpret_cast<int*>(address))
			<< endl;
		cout << "アドレス:" << &data
			<< "\t値:" << data
			<< endl;
	}

	// キー入力待ち
	rewind(stdin), getchar();
	return 0;
}
出力例

コード:

アドレス一致
アドレス:00EFF904      値:100
アドレス:00EFF904      値:120

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 同一アドレスが、異なる値を指している?

#2

投稿記事 by みけCAT » 7年前

未定義動作になるかは確認していませんが、値は最適化によりプログラム中に直接埋め込むことで保っていると考えられます。
実際、Compiler Explorerのx86-64 gcc 4.8.1で確認すると、
addressを使った出力部分ではメモリから値を読みだしているのに対し、dataを使った出力部分では即値の120を使っていました。

以下、Assembly Outputの転載
► スポイラーを表示
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

inemaru
記事: 108
登録日時: 7年前

Re: 同一アドレスが、異なる値を指している?

#3

投稿記事 by inemaru » 7年前

返答ありがとうございます。
挙動について、納得できました。

今回の状況は、
dataの初期化値が定数になっていることが、原因だったようです。

逆に、dataの初期化値を変数にすると
アドレスから値を取得するので、
const変数でも書き換えできてしまうことがわかりました。

コード:

// 元になるconst変数
const int data = rand();
また、アセンブリで実際の動作を確認することを覚えました。

特に、Compiler Explorer に関して良Webツールを
知ることができて良かったです。

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

閉鎖

“C言語何でも質問掲示板” へ戻る