初歩的な質問で申し訳ないんですが
int a;
で作った変数があったとします。
このaという変数に、0という値を格納(a = 0)しようが、10000000という値を格納しようが
容量は変わらないって本当ですか?
要は、int a = 0; int b =10000000;では
aもbも、使っている容量自体は変わらないという認識でよろしいですか?
だとすれば、画像ハンドルも?
変数aにLoadGraphを使って画像のハンドルを入れようが
ただの数字が入っている変数aと、
容量は変わらないということでしょうか?
宣言した変数の用量は中身の値に関わらず一定ですか?
- Hiragi(GKUTH)
- 記事: 167
- 登録日時: 13年前
- 住所: 大阪府
- 連絡を取る:
Re: 宣言した変数の用量は中身の値に関わらず一定ですか?
容量、といいますか、int型が宣言された時点で32bit(或は16bit)はメモリ上で「確保」されますので、その確保されたところに値を書き込む感じでしょうか、
良くある例で言うならば、変数は箱であるとよく比喩されますが、箱の中にどんな値を入れようとも箱の大きさは変わらんわけです。
メモリー内部では大きな値の分メモリセルの状態が1である(ONである)から容量が変わってるといえなくはないかもしれませんが...
画像ハンドルに関しては、int型の変数に画像そのものが入ってるわけではなく、int型の変数に入るのは画像の位置を示す情報であるということです。
良くある例で言うならば、変数は箱であるとよく比喩されますが、箱の中にどんな値を入れようとも箱の大きさは変わらんわけです。
メモリー内部では大きな値の分メモリセルの状態が1である(ONである)から容量が変わってるといえなくはないかもしれませんが...
画像ハンドルに関しては、int型の変数に画像そのものが入ってるわけではなく、int型の変数に入るのは画像の位置を示す情報であるということです。
だいがくせい!
Re: 宣言した変数の用量は中身の値に関わらず一定ですか?
レス、ありがとうございます。
ただ、この例えを現実的に考えた場合ですが、
箱のサイズは変わらなくても、
その中に入れるものによって、重さは変わるじゃないですか?
そこんところ、変数ではどうなんかなーって思いまして。
ちなみに、変数に入れる値の限界が2147483647らしいですが
例えば、ゲーム中に
それ以上の数を代入、ないしは、インクリメントを繰り返しそれ以上の値を超えたら
問答無用でエラーになってゲームが止まるんでしょうか?
そうですよね、そう勉強したはずなんですけど、、、、、Hiragi(GKUTH) さんが書きました:変数は箱であるとよく比喩されますが、箱の中にどんな値を入れようとも箱の大きさは変わらんわけです。
ただ、この例えを現実的に考えた場合ですが、
箱のサイズは変わらなくても、
その中に入れるものによって、重さは変わるじゃないですか?
そこんところ、変数ではどうなんかなーって思いまして。
ちなみに、変数に入れる値の限界が2147483647らしいですが
例えば、ゲーム中に
それ以上の数を代入、ないしは、インクリメントを繰り返しそれ以上の値を超えたら
問答無用でエラーになってゲームが止まるんでしょうか?
Re: 宣言した変数の用量は中身の値に関わらず一定ですか?
それは使用する言語によって変わると思います。
アンセーフな言語のc、c++では致命的なメモリリークをしない限り大丈夫ですが、(逆にその適当さがバグの抜きにくさの原因でもあります)割と厳しいc#やjavaではたしか強制終了させられたと思います。
phpは割とリーク、オーバーフロー系は起ころうがガン無視です。この前それを体験して泣きました。
ちなみにメモリリークとかオーバーフローをあえて行うことでwebサイトを攻撃する方法がありますし、プロアクションリプレイのようなチートツールもそれらを使ってゲームをバグらせる事でお金やHP上限をMAXにしています。
アンセーフな言語のc、c++では致命的なメモリリークをしない限り大丈夫ですが、(逆にその適当さがバグの抜きにくさの原因でもあります)割と厳しいc#やjavaではたしか強制終了させられたと思います。
phpは割とリーク、オーバーフロー系は起ころうがガン無視です。この前それを体験して泣きました。
ちなみにメモリリークとかオーバーフローをあえて行うことでwebサイトを攻撃する方法がありますし、プロアクションリプレイのようなチートツールもそれらを使ってゲームをバグらせる事でお金やHP上限をMAXにしています。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: 宣言した変数の用量は中身の値に関わらず一定ですか?
自分はC++です。
自分で実験するのはまだ怖いのもありまして、、。
教えてくださいまして、感謝です。
ご回答くださいましたみなさま、ありがとうございました。
自分で実験するのはまだ怖いのもありまして、、。
教えてくださいまして、感謝です。
ご回答くださいましたみなさま、ありがとうございました。
Re: 宣言した変数の用量は中身の値に関わらず一定ですか?
昔と違っていまのOSは致命的な領域破壊を検知したら強制的にプロセスを止めるからそこまで警戒しなくてもいいと思う。むしろ一度二度経験(実験)しとけば次回から同じ症状に陥った時に原因特定が多少楽になるよ。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: 宣言した変数の用量は中身の値に関わらず一定ですか?
C言語では処理系依存です。カマキリ さんが書きました:ちなみに、変数に入れる値の限界が2147483647らしいですが
int型の場合、規格上少なくとも-32767~32767の整数は格納できます。
C言語では、符号付き整数がオーバーフローした時の動作は未定義だったと思います。TOMY さんが書きました:アンセーフな言語のc、c++では致命的なメモリリークをしない限り大丈夫ですが
よって、大丈夫とは限りません。
また、「致命的なメモリリークをしない限り大丈夫」というのは誤りです。
例えば、
#include <stdio.h>
int main(void) {
volatile int a[1];
puts("test1");fflush(stdout);
a[1234567] = 123;
puts("test2");fflush(stdout);
printf("test3 %d\n", a[1234567]);fflush(stdout);
return 0;
}
Javaではint型がオーバーフローしても強制終了にはならないと思います。TOMY さんが書きました:割と厳しいc#やjavaではたしか強制終了させられたと思います。
class A {
public static void main(String[] args) {
int a = 2147483647;
System.out.println(a);
a++;
System.out.println(a);
}
}
using System;
public class Test
{
public static void Main()
{
int a = 2147483647;
Console.WriteLine(a);
a++;
Console.WriteLine(a);
}
}
プロアクションリプレイの実装は知りませんが、チートツールはそんなまわりくどいことをせず、直接メモリ上の値を書き換えると思います。TOMY さんが書きました:プロアクションリプレイのようなチートツールもそれらを使ってゲームをバグらせる事でお金やHP上限をMAXにしています。
また、TASではバッファオーバーランを使って(?)任意のコード(?)を実行するものがあります。
追記:この動画はそういう原理ではないかもしれません
[nico]http://www.nicovideo.jp/watch/sm20328346[/nico]
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 宣言した変数の用量は中身の値に関わらず一定ですか?
オフトピック
言語のマイナーな部分を……。みけCAT さんが書きました:C#でも、実験結果では強制終了になりませんでした。TOMY さんが書きました:割と厳しいc#やjavaではたしか強制終了させられたと思います。
using System;
class Program
{
private static void Main ()
{
try
{
CallUnchecked();
Console.WriteLine("CallUnchecked succeeded.");
}
catch (Exception e)
{
Console.WriteLine("CallUnchecked raised {0}", e.GetType().Name);
}
try
{
CallChecked();
Console.WriteLine("CallChecked succeeded.");
}
catch (Exception e)
{
Console.WriteLine("CallChecked raised {0}", e.GetType().Name);
}
}
private static void CallChecked ()
{
checked
{
var n = Int32.MaxValue;
++n;
}
}
private static void CallUnchecked ()
{
unchecked
{
var n = Int32.MaxValue;
++n;
}
}
}
しかし,uncheckedコンテキスト内においてはオーバーフローの検出は行いません。
細かいことは,C# 5.0の言語仕様の,6.2.1 明示的な数値変換の一覧表 (英語では6.2.1 Explicit numeric conversions) に規則が書かれています。
なお,MSのcscコンパイラにおいて,デフォルトはuncheckedコンテキストです。
Re: 宣言した変数の用量は中身の値に関わらず一定ですか?
C++で、int型のサイズが32bitで出力された場合。
int a = 0; int b =10000000;
一見すると桁が違うから大きさが違うように見えるが、0も一桁ではない。仮にintが32bitなら0は
00000000000000000000000000000000
という32bitの値になる(2進数)
10000000は
00000000100110001001011010000000
という32bitの値になる(2進数)
この32桁の2進数は違う値を示すが、桁数(を表現するために必要な領域)は同じ。
[hr]
あまり他人の回答に鉞は投げたくないのだが、
たまたま、偶然にも32bitや16bitで表現されることが多いだけである。各コンパイラがドキュメントで警告しているように、int型のサイズは実行環境に依存することを踏まえ、サイズに依存するコードを書いてはいけない。上記の記述は初心者の誤解を産みがちで、オーバーフローよりもずっと「危険」なことに繋がりかねない。もしかしたら今後intは64bitが当たり前の時代だって来るかもしれない。
ただし、互換があるだけでC++でこれはおすすめしない。C++標準ライブラリlimitsにstd::numeric_limitsがあるので、これを使うべきである。std::numeric_limits<int>::max()とすれば最大値を取得できる。
標準ヘッダcstdintに、C++11以降では型のサイズをある程度指定できる型が定義されている。以下は一例。
実行環境における最大の整数型
intmax_t
最低でも指定bit数を持つ型
int_least32_t
int_least16_t
最低でも指定bit数を持ち、最速で計算できる型
int_fast16_t
int_fast32_t
C++03までの環境でも、boostに同様のものがある。boost.integerのほうが汎用的である。
ちなみに各コンパイラ固有の、専用のサイズ指定の型がある場合があるが、一般的には型のサイズは標準ライブラリかboostの型を使うべきである。組み込みは考えない。
std::numeric_limits<unsigned int>::max() + 1
の結果は0になることが定められているということだ。
宣言された時点で確保、というのも微妙なラインだが、あまりほじくっても仕方ないので触れないことにする。
規格の文面はWorking Draft, Standard for Programming Language C++ N4296より引用した。
§ 3.9.1 Fundamental types [basic.fundamental]
これはワーキングドラフトであり正式な規格ではないが、intに関する文面はC言語と互換が残されていることもあり、ほとんど変更されていないため、問題はないだろう。
int a = 0; int b =10000000;
一見すると桁が違うから大きさが違うように見えるが、0も一桁ではない。仮にintが32bitなら0は
00000000000000000000000000000000
という32bitの値になる(2進数)
10000000は
00000000100110001001011010000000
という32bitの値になる(2進数)
この32桁の2進数は違う値を示すが、桁数(を表現するために必要な領域)は同じ。
[hr]
あまり他人の回答に鉞は投げたくないのだが、
というのは厳密には間違いで、あらぬ誤解を生みかねない。Hiragi(GKUTH) さんが書きました:int型が宣言された時点で32bit(或は16bit)はメモリ上で「確保」されます
int型は実行環境における自然なサイズで表現されると書かれている。つまり、規格には32bitや16bitと言ったルールは存在しない。Plain ints have the natural size suggested by the architecture of the execution environment; the other signed integer types are provided to meet special needs.
たまたま、偶然にも32bitや16bitで表現されることが多いだけである。各コンパイラがドキュメントで警告しているように、int型のサイズは実行環境に依存することを踏まえ、サイズに依存するコードを書いてはいけない。上記の記述は初心者の誤解を産みがちで、オーバーフローよりもずっと「危険」なことに繋がりかねない。もしかしたら今後intは64bitが当たり前の時代だって来るかもしれない。
int型の最大値はINT_MAX、最小値はINT_MINとして、標準ヘッダclimitに定義される。これはCの標準ライブラリだが、intに関しての規格はC言語と互換があるため、問題ない。that is, large enough to contain any value in the range of INT_MIN and INT_MAX, as defined in the header <climits>.
ただし、互換があるだけでC++でこれはおすすめしない。C++標準ライブラリlimitsにstd::numeric_limitsがあるので、これを使うべきである。std::numeric_limits<int>::max()とすれば最大値を取得できる。
符号あり、符号なしのint型はC言語規格と互換がある。The signed and unsigned integer types shall satisfy the constraints given in the C standard, section 5.2.4.2.1.
標準ヘッダcstdintに、C++11以降では型のサイズをある程度指定できる型が定義されている。以下は一例。
実行環境における最大の整数型
intmax_t
最低でも指定bit数を持つ型
int_least32_t
int_least16_t
最低でも指定bit数を持ち、最速で計算できる型
int_fast16_t
int_fast32_t
C++03までの環境でも、boostに同様のものがある。boost.integerのほうが汎用的である。
ちなみに各コンパイラ固有の、専用のサイズ指定の型がある場合があるが、一般的には型のサイズは標準ライブラリかboostの型を使うべきである。組み込みは考えない。
符号なしint型に関しては、2nを法とするモジュロ算術に従うことが定められている。つまり、符号なし整数型はオーバーフローしない。Unsigned integers shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.
std::numeric_limits<unsigned int>::max() + 1
の結果は0になることが定められているということだ。
宣言された時点で確保、というのも微妙なラインだが、あまりほじくっても仕方ないので触れないことにする。
規格の文面はWorking Draft, Standard for Programming Language C++ N4296より引用した。
§ 3.9.1 Fundamental types [basic.fundamental]
これはワーキングドラフトであり正式な規格ではないが、intに関する文面はC言語と互換が残されていることもあり、ほとんど変更されていないため、問題はないだろう。
Re: 宣言した変数の用量は中身の値に関わらず一定ですか?
みけCATさん私の間違った解答にご指摘ありがとうございます。
割と自分の知識と経験というのはあてにならないものですね・・・
次回からは黙るようにします。
割と自分の知識と経験というのはあてにならないものですね・・・
次回からは黙るようにします。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。