配列の初期化で値が代入されない原因とは?

このQ&Aのポイント
  • 配列の初期化に問題があります。
  • 配列を初期化する際に、要素数を指定せずに初期化している可能性があります。
  • また、初期化する値に誤りがあるかもしれません。
回答を見る
  • ベストアンサー

配列の初期化

昨日書いたコードを今日ビルドして実行したところ、 以下のように初期化した配列に値が代入されなくなりました。 どうも初期化前に戻っているような感じです。 y = 0; x = 6; int point_y[20] = { 0 }; int point_x[20] = { 0 }; c = 0; point_y[c] = y; point_x[c] = x; c = c + 1; この時点で point_y[0] には0, point_x[0]には6が入ってほしいのですが point_y[c]にカーソルを当てて中身を見ると point_y[0] = 11372064; point_y[1] = 1742984488; といった具体です。point_x[c]の中身も同じような感じです。 何が原因か悩んでいます。 もしアドバイスいただけると助かります。 どうぞよろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • KEIS050162
  • ベストアンサー率47% (890/1879)
回答No.1

見たところおかしいところはありません。 一応、念のためですが、 x,y ともに intですね? int point_y[20] = { 0 }; は、point_y[0] のみ初期化する意図ですね?0~19すべて初期化するのであれば、 {0,0,0, … } と0を20個書いてください。 ところで、”この時点”というのがどの時点か分かりませんが、恐らくなんらかのデバッガだと思いますが、 ステップ実行で見るなら、 c=c+1; まで実行させてから変数の内容を確認してみてください。 もっと確実なのは、printf()文を入れて出力させる方法です。

rosafilipes
質問者

お礼

ありがとうございました。 配列を20個ぶんゼロで初期化し、 printfで出力したところ、正常に値が入っていることを確認できました。 ただ、デバックしてカーソルを当てるとやはり8桁や10桁の乱数?が入っているので とても不思議です。

その他の回答 (8)

  • uyama33
  • ベストアンサー率30% (137/450)
回答No.9

NO6 です。 失礼しました。 原因は、リリースモードでビルドしたものを デバッグしていたからでした。 デバッグモードでビルドしたものを デバッグしたら、きれいに表示されました。 間違った情報で、混乱させました。 ごめんなさい。

rosafilipes
質問者

お礼

いえ、2回もコメントを書いてくださってありがとうございました。 リリースモード、デバックモード、意識します。 今回はデバックモードです。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.8

VC++の場合ですが、releaseモードの場合、変な値が表示されることはあったと思います。 いずれにせよ、printfで正しく表示されるのであれば、実行結果としては正しいわけで、問題ではありません。 なぜこうなるのか、ということがどうしても気になるのであれば、アセンブリ出力を追ってみるとわかるのではないかと思います。

rosafilipes
質問者

お礼

なるほど、VC++のreleaseモードで発生するのですね。 環境はそれかもしれません。 printfでの結果ありきで安心してよさそうで、ホッとしました。 ありがとうございました!

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.7

既に指摘されていいますが… 「この時点」というのはどこまで実行した状態です? 少なくとも、 c = 0; が実行されていない状態で point_y[c]やpoint_x[c]を参照した場合、内容は保証されませんよ? cに入っている値が-78とかなら、 point_y[c]はpoint_y[-78]を参照しますし、 point_x[c]はpoint_x[-78]を参照します。 で、環境って結局なんなんでしょう??? >以下のようなコードを書いて、 >デバッガーで >b64out >をチェックすると、先頭部分が >フフフ。。。 >となっていて、変換に失敗しているのかなと思いましたが、 どの時点で確認したのでしょう? VSでデバッグ構成でビルドすると未初期化のローカル変数は0xCC(デバッガで見ると半角のフに見える)で埋められていたかと記憶していますが。 https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/c904.html の「(4) /RTCs [Visual Studio 2005, Windows]」にもちょこっと書かれていますけど。 掲示されたコードだとおそらく base64_encode(p, (p+num), (char *)b64out); から戻って来るまでは値は不定(未初期化:デバッグ構成だと0xCCで埋まっていますし、リリース構成だと本当の意味で不定)になっているかと思われますが…。 VSのデバッグで(ウォッチの)値が変になる…という現象に出くわしたことはないですね。 # 自分が組み込んだ不具合以外では。 現状、仕事で使用しているHEWの方がブレークポイントで止めた時に表示される値がおかしい…ということはありますが。 スコープ内のハズなのにそんな変数は無い。とか言われたり。 # たぶん使い方とかの問題だと思いますけど…(最適化掛かっていたりするのもあるやも知れん)

rosafilipes
質問者

お礼

該当行まで実行したあとの状態です。 「スコープ」と言うのですね。 最適化?とはなにか。。。というレベルですので、到底そういった凝ったことはできていません。 このようなことは今までなかったので(整数が入るはずの変数にカーソルを当てると妙な桁数の数字が表示される)あえて質問投稿しました。 やはり不思議現象なのですね。 コメントありがとうございました。

  • uyama33
  • ベストアンサー率30% (137/450)
回答No.6

私は、とても優れたコンパイラ VS2005 を使っています。 (高いお金を払って買ったものです。) 以下のようなコードを書いて、 デバッガーで b64out をチェックすると、先頭部分が フフフ。。。 となっていて、変換に失敗しているのかなと思いましたが、 さらに、このデータを使って次の操作をすると、 正確に変換されていたことが確認できました。 もしかしたら、MSのコンパイラを使っていませんか? そうなら、あきらめましょう。 MSには勝てませんから。 int num, i; char b64out[512]; char plain[256]; sprintf_s(plain, sizeof(plain), "%s\t%s\t%s", oc_Sender, oc_Sender, oc_POP3password); num = (int)strlen(plain); char* p = plain; for (i = 0; i<num; i++) if (p[i] == _T('\t')) p[i] = 0; base64_encode(p, (p+num), (char *)b64out); でも、最近は無料になったから、許してやることにします。

  • na-_-mi
  • ベストアンサー率0% (0/1)
回答No.5

> printfで出力したところ、正常に値が入っていることを確認できました。 > ただ、デバックしてカーソルを当てるとやはり8桁や10桁の乱数?が入っているので ということなら、デバッガーの使い方を間違えていませんか? ちゃんと目的の位置 > point_y[c] = y; > point_x[c] = x; > c = c + 1; まで実行した*後*に中身を見ていますか? それから、intの配列を0で初期化するのは、C言語では > int point_y[20] = { 0 }; > int point_x[20] = { 0 }; で全く問題ありません。 C++言語なら int point_y[20] = {}; int point_x[20] = {}; でも良いです。

rosafilipes
質問者

お礼

その行まで実行したあとに確認して、の状態で困ってこちらに投稿しました。 なぜなのか、、、printfするとカーソルを当てたときと違い正常に値が入っている ことがわかったのですが。 気になります。 アドバイスありがとうございました。

noname#208507
noname#208507
回答No.4

Tacosanさんの言うとおり、int point_y[20] = { 0 }; で全て 0 で初期化されるはず。わざわざ 0 を20個並べる必要はありません。

rosafilipes
質問者

お礼

ありがとうございました。 そのようにして初期化します。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

ああ, #2 は自分で矛盾したこと書いてるな. int point_y[20] = { 0 }; で point_y の全要素を 0 で初期化してるから, ここを通っていればどの要素も 0 じゃないとおかしい. ということで, あとはあなたがどのような操作をしたかによる. つまり 「point_y[c]にカーソルを当てて中身を見る」 までの具体的な操作を全部書いてもらわないとどうにもならない. 書いてもらったらどうにかなるかといわれると, それは困るところだ.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

とりあえず point_y[1] がおかしいのは「おかしいのが当然」だな. それ以上は具体的な情報がないとどうにもならん. 例えば, 最低限 ・実際に実行できる完全なプログラム ・動かした環境 がないと答えようがない. ちなみにだが, 配列の初期化では「不足する要素は 0 で初期化」なので int point_y[20] = { 0 }; は「point_y の全ての要素を 0 にする」という効果を持つぞ>#1.

rosafilipes
質問者

お礼

いろいろと情報不足な質問で申し訳ありません。 配列初期化の方法、勉強になりました。 ありがとうございました。

関連するQ&A

  • 配列とポインタについて

    #include <stdio.h> int main() { char x[3]; char *y; x[0]='a'; x[1]='b'; x[2]='\0'; y="abc"; printf("xの値は%s\n",x); printf("yの値は%s\n",y); } 通常の配列宣言では、このままだと文字列をまとめて 代入できないのに対して、ポインタ変数ならまとめて代入することができるのは何故ですか?そういう仕組みだと言われてしまえば、それまでなんですが・・・

  • 多次元配列の構造体の初期化

    タイトル通りです。やり方がわかりません。 構造体変数の初期化や多次元配列の初期化が載ってるページは多いのですが、コレだけは調べても解りませんでした。 typedef struct{ int flag; ~~~~~(略)~~~ }map_t; map_t map[64][64]; の後、map_t型のmap64*64の int flag全てに値を代入したいのですが 詳しいやり方が解りません。 int hensuu[3][3]={   {1,2,3},{4,5,6},{7,8,9} }; 普通の多次元配列みたいにmこんな感じでやりたいんですけど… 初心者でスミマセン。回答いただけたらありがたいです。

  • c言語の問題です。解説と解答をお願いします

    (1) doube a[3][4]で宣言された2次元配列の要素a[y][x]に割り当てられるメモリのアドレス&a[y][x]を数式で表せ。x∈{0,1,2,3},y∈{0,1,2}である。 (2) 下記の宣言文によって複数個の配列要素に初期値を代入した。各配列要素に代入される値を説明しなさい。 char b[]={‘X’,’Y’,’Z’}; char c[]=“xyz”; char *d[]={“ONE”,”TWO”,”THREE”}; int e[3][2]={1,3,5,7,9,11}; お願いします。

  • 多元配列の0初期化

    たびたびお世話になっております。 PERL 5.14.2 (Windows 7)を コマンドプロンプト上から動かしています。 use strict; use warnings; @multi_dimension_arrays; # $multi_dimension_array[$x][$y][$z] というような配列の中身を最初に0初期化したいのですが $x, $y, $zがどれだけ増えるかわかりません。 (0初期化していないので、大小比較などでエラーとなることがあります) 0初期化の方法をお教えください。

    • ベストアンサー
    • Perl
  • 配列に値を入れるのを簡略化

    配列に値を入れるのに簡略化する方法はないのでしょうか? ---ソース--- //グローバルで初期化 static int a[5]={0}; void main void{ //メイン関数で値を代入 宣言と共に初期化する場合はa[5]={ 4,6,9,2,7 } と簡略化できるのに値を代入する場合はいちいちひとつづつ値を代入しないといけないの? a[0]=4; a[1]=6; a[2]=9; a[3]=2; a[4]=7; }

  • VBAの初期化について

    VBAの初期化について 変数Xに100という値を初期値として代入したいのですが。 Option Explicit Dim X As Integer X =100 と書くとコンパイルエラーになります。 C言語では int X=100 と初期化できますが、 VBAではどのようにすればいいのでしょうか?

  • 配列

    public void test(int[] x){ ... } というメソッドに配列を渡したいとき、 test(new int[5]); は可能ですが、 int[] a = {0,1,2,1,0} という書式が可能なことから、 test( {0,1,2,1,0} ); としてみたのですが、コンパイルでひっかかります。 {}による配列生成は初期化のみに限定されているのでしょうか。 値の入った配列をこのtestに入れてやりたい場合は、 int[] a = {0,1,2,1,0}; test(a); としていかないといけないのでしょうか。

    • ベストアンサー
    • Java
  • メモリの初期値

    C言語の勉強をしている者です。 やっとこさポインタのところまでやってきまして、いろいろ試しているところなのですが、不可解な事が起こったので質問させてください。 int型の配列を作って、初期化しないままその配列[0]に入っている値を覗くと -858993460 という値が入っていました。 もう一度配列を作り、メモリのアドレスを確認すると、前に作った配列とポインタのアドレスが同じだったので そこに0を入れました。 当たり前ですが配列[0]の値は0でした。 さらにもう一度配列を作り、[0]のアドレスの中身を覗くと -858993460 という値に戻っていました ※配列[0]のアドレスは常に一緒です。 なぜこんな訳のわからない数字( -858993460 )に初期化されているんでしょうか 一度0に初期化したのなら次は0のままになっていると予測していたのですが、どうなっているんでしょうか どなたか理由のわかる方いませんか

  • 配列のとれる領域

    #include<stdio.h> #define X_wid 512 #define Y_wid 512 main(int argc,char *argv[]) { int x=0,y=0,X=0,Y=0,c; int input[X_wid+1][Y_wid+1],middle[X_wid][Y_wid]; FILE *fp,*fp_w;  :  : } middle[X_wid][Y_wid]配列のとる領域の値を大きくとるとエラーメッセージがでてしまいます。 [1][1]や[X_wid][Y_wid]などは正常にコンパイルできるのですが、[X_wid*2][Y_wid*2]みたいに領域を多くするとエラーメッセージがでてしまいます。 やはり、配列のとれる領域は制限があるのでしょうか? また、それでもその領域([X_wid*2][Y_wid*2)を使わなければならない時はどうすればよいでしょうか?

  • java の配列についての質問です。

    java の配列についての質問です。 java 及び C++についての知識は初心者です。 public abstract class Plan implements Shapeable { Shape[] shape = new Shape[5]; Shape[0] = new Rectangle(10,10,10,10); // x,y 座標 及び 長さ、高さ Shape[1] = new Triangle(10,10,30,10,20,20); // 3点間の座標        Shape[2] = new Triangle(20,10,40,10,30,20);        Shape[3] = new Triangle(15,15,35,15,25,25); Shape[4] = new Circle(20,20,20); // 円の座標と半径     public float[] calculaterAreas(){ ??????????????????? } 内容としては複雑なのですが、三角形、四角形、円の面積をShapeというclassの配列にあるデータ(座標や長さなど) を使ってShapeの配列のデータを置き換えてfloatのデータとして返すんですが・・・・。どうやっていいのかさっぱり わかりません。面積については、Rectangle,Triangle,Circleのクラスでそれぞれ計算できるようになっているのですが、それを持ってくる方法もわかりません・・・どうしたらいいのか教えてください 宜しくお願いします。 ちなみに Rectangle,Triangle,Circle class の area の メソットは --- Rectangle class public class Rectangle extends Shape{ int x; int y; int width; int height; public float area(Rectangle r) { return r.width * r.height; } --- Circle class public class Circle extends Shape{ int x; int y; int radius; public float area(Circle c) { return (float) (c.x * c.y * 3.14); } } --- Triangle class public class Triangle extends Shape{ int x; int y; int x2; int y2; int x3; int y3; public float area(Triangle t) { float dt1,dt2,dt3; float s1; float area1; dt1 = Point.distance(x, y); // Point は dt2 = Point.distance(x2, y2); dt3 = Point.distance(x3, y3); s1 = (dt1+dt2+dt3)/2; area1 = (float) Math.sqrt((s1-dt1)*(s1-dt2)*(s1-dt3)); return area1; } } *** Shape class public abstract class Shape implements Shapeable { public abstract float area(Shape obj); } *** Shapeable インターフェイス public interface Shapeable { float area (Shape obj); } ** コンストラクター等は省略してあります。

    • ベストアンサー
    • Java

専門家に質問してみよう