質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.54%

  • C

    4397questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    4319questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • OS

    232questions

    OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

  • アーキテクチャ

    89questions

    アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

64bitでポインタのオーバーフローが起こるのでは??

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,286

strike1217

score 568

ふと思ったのですが、
「ポインタに入るアドレスの値がそのポインタ型の最大値を超えたら、オーバーフローが起こるのでは??」
と・・・

確認プログラムを作成してみました。

#include<stdio.h>

int main() {
    char h = 1000; // わざと
    int n = 255;
    long m = 4294967295;
    printf("%d\n", h);
    printf("char : 255 = 0x%x\n", n);
    printf("unsigned int : 4,294,967,295 = 0x%x\n", m);

    int i = 90;

    char a = 'A';
    char *p = &a;
    printf("&a : 0x%p, sizeof(char *) = %d Bytes, sizeof(int *) = %d Bytes\n", p, sizeof(char *), sizeof(int *));
    return 0;
}


結果は以下のようになりました。
-24
char : 255 = 0xff
unsigned int : 4,294,967,295 = 0xffffffff
&a : 0x0060FABF, sizeof(char *) = 4 Bytes, sizeof(int *) = 4 Bytes

int * を例に取ります。
大きさは4Byteなので 0x00000000 ~ 0xffffffff までのアドレスなら格納できることになるはずです。

以下のようなものを見つけました。
リンク内容

32bit OSなら、4GBまでなのでこれでも問題なさそうですが、64bitになるとアドレス空間が大きくなります。

例えば、メインメモリを32GB(8GB x 4スロット)積んでいたとします。
以前も質問をしたのですが、(リンク内容)1つのアプリケーションで、10億個の配列を使用した場合、12x10^9になるので、メモリは12GB搭載していないと動かない・・・ということになると思います。

これって、0xffffffff を超えるようなアドレスの値を int * に入れ込むと、オーバーフローになりませんか??

これ、やばいような気がするんですが・・・実際はどうなっているのですか??
教えてください。

[追記]
環境を追記しますね。
windows 64bit
ファイル拡張子 .c です。
visual studioでコンパイルしてみました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+4

環境(32/64bit)によりポインタ型のサイズも異なります。
C/C++における整数型には気をつけよ

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/23 19:11

    c++ でも同じようにやってみましたが、(int *) 4bytesから変化がないです><
    どうしてでしょう??

    キャンセル

  • 2017/01/23 19:14

    ビルドオプションが不明なのであてずっぽうですが、ターゲットが32bitになっているのでは?

    キャンセル

  • 2017/01/23 19:15

    ビルドオプションな何も入れてないですね。

    visual studio は標準で32bitになってしまうんですかね?・・・

    キャンセル

  • 2017/01/23 19:31

    えーと、
    どの方をベストアンサーにすれば良いのか迷ったのですが、高評価だったので、ベストアンサーにさせてもらいます。

    キャンセル

+3

「オーバーフロー」という言葉を正しく理解していらっしゃらないように思います。

「算術オーバーフロー」は、演算の結果が、その結果を格納すべきレジスタの表せる値の範囲外になることを意味します。レジスタに格納された値はもはや期待される結果を表しませんので、オーバーフローがあったか否かを知る必要があります。

スタックのような構造では必要な記憶域の大きさが動的に変化しますが、大きさが上限に達してそれ以上利用できなくなることを、「スタックオーバーフロー」と言います。

一方、あるバッファ領域にデータを格納する際、データの長さのチェックを怠りバッファ長を超えて書き込んでしまうことを「バッファオーバーフロー」と言います。

変数 (レジスタやメモリなど) へのデータの格納の場合、格納に必要な記憶域の大きさがデータの大きさを超えていれば、正しい情報を格納できません。これはあらかじめ必要な大きさの記憶域を確保しなかったために起きる問題です。なんらかの演算の結果が期待通りでないこととは違いますし、記憶域の大きさを動的に変化させることができたわけでもありませんし、データ長のチェックが必要なわけでもありません。つまり、算術オーバーフローでも、スタックオーバーフローでも、バッファオーバーフローでもありません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/23 19:12

    ありがとうございます!

    おへ・・・
    そうなんですか!

    キャンセル

+2

64bit環境のgccで次のようなプログラムを動かしてみました。

#include <stdio.h>

int main() {
  printf("%d %d %d %d\n",
         (int)sizeof(int), (int)sizeof(int*),
         (int)sizeof(size_t), (int)sizeof(intptr_t);
}


結果は4 8 8 8となります。can110さんがおっしゃるようにintは「そのプラットフォームでの自然な語長」ではありますが「そのプラットフォームでのメモリーの空間を完全に表現できるビット数」とは定義されていません。そうした目的にはsize_t(訂正: intptr_t)が妥当と言えると思います。


訂正:
raccyさんのコメントみて気づきましたがsize_tではなくてintptr_t/uintptr_tが空間サイズを表現するのに適切な型のようでした。失礼しました。
size_tは空間の大きさを表現するものという定義ではなく配列の指標、構造のサイズ、プログラム内の最大のメモリオフセットの保持が可能という意味あいのものでほぼ空間サイズとして使えると思っていたのですがズバリintptr_t/uintptr_tの定義が空間サイズなんですね。
追記:
ついでに上のコードで"%d"でsize_t型を印字しようとしているのが怪しいので直しました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/23 18:50

    size_tはsizeof等の結果を受け取るに十分なサイズであればいいので、ポインタ自身が十分に入るサイズとは限らないのでは無いのでしょうか?
    参考: http://stackoverflow.com/questions/1464174/size-t-vs-intptr-t

    キャンセル

  • 2017/01/23 19:14

    ありがとうございます
    Linuxでやったのですかね・・・

    やはり、OSによっても異なるみたいですね。

    キャンセル

  • 2017/01/23 19:29

    http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10119811170

    size_tに関して、
    参考になるかわかりませんが、KSwordOfHasteさんと似たようなことを言っているような気がするものを見つけました。

    キャンセル

  • 2017/01/23 20:05

    raccyさんのコメントを拝見しました。正直、size_tはレガシーな知識だったようですw;
    stackoverflowの回答や他のを見てみるとintptr_t/uintptr_tが空間の大きさを扱うには適切のようですね。
    intptr_tは使ったことなかったです・・・失礼しました!

    キャンセル

  • 2017/01/23 20:28

    linuxじゃなくてcygwin64でした・・・(小声)

    キャンセル

  • 2017/01/23 20:38

    左様でございますか!

    キャンセル

+2

こんにちは。

これって、0xffffffff を超えるようなアドレスの値を int * に入れ込むと、オーバーフローになりませんか??

32ビット・ビルドしている時は当然オーバーフローします。
64ビット・ビルドならポインタも64ビットあるので余裕です。

これ、やばいような気がするんですが・・・実際はどうなっているのですか?? 

C/C++ではオーバーフロー/アンダーフローが問題を起こさないようにプログラムすることはプログラマの責任です。この件に関してコンパイラはあまりサポートしてくれません。

でも、メモリのあるところしかアクセスしないプログラムであれば通常は問題でないです。32ビットのポインタでボイントできないメモリを割り当てられることはありませんから。
逆に言えば、32ビット・ビルドしたプログラムは4GBytesを超えるメモリを通常の手順では使えません。だから最近は64ビットOSが良く使われます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/23 19:13

    visual studio は標準で、32bitビルドになっているんでしょうかね??・・・

    キャンセル

  • 2017/01/23 19:20

    Visual C++はデフォルトでは32ビット・ビルドです。
    64ビット・ビルドするには下記手順などを行います。
    https://msdn.microsoft.com/ja-jp/library/9yb4317s.aspx

    キャンセル

  • 2017/01/23 19:23

    げげげげ!!

    やだ!
    32bitのプログラムで64bitの考察をしてしまいました。
    きゃあああああ><

    キャンセル

  • 2017/01/23 19:33

    なるほど。たぶん64ビットOSでビルドしてたのですね。ドンマイです。

    キャンセル

同じタグがついた質問を見る

  • C

    4397questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    4319questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • OS

    232questions

    OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

  • アーキテクチャ

    89questions

    アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます