激凹みから立ち直る方法

.malloc()については以前も質問させて頂きましたが
新たな疑問についてご教示下さい。
・下記のプログラムでmalloc()とrealloc()は正常に作動していると思いますが、入力表示を有効にすると下記の「エラー表示」が表示されます。
・「エラー表示」されてもプログラムは最後まで実行される様です。
・n=400までは表示されます。
・この理由が分かりません、ご教示下さい。
・malloc()関係は不安定な関数群でしょうか?

■「エラー表示」について
***********************************************************
問題が発生したため、***.exeを終了します。ご不便をおかけて申し訳ありません。
作業途中・・・・・
この問題を「マイクロソフト」に報告ください。
************************************************************
・一部ですが以上の様なエラー表示です。

//malloc_2
#include <stdio.h>
#include <stdlib.h>
void MylnOut(int ,int ,int *);
//**************************************************************
//MAIN
//**************************************************************
int main()
{
int *map;
int X=10,Y=10,n;

/* 疑似2次元配列確保と初期表示 */
  printf("初期値.... \n");
  map=(int *)malloc(sizeof(X*Y));
// MylnOut( X, Y, map);

/* 変更数値入力 */
for(n=1;n<401;n++){
  X=rand()%50+2;
  Y=rand()%50+2;
  printf("変更..%3d回目 X=%2d Y=%2d\n",n,X,Y);

/* 領域変更と表示 */
  map=(int *)realloc(map,sizeof(X*Y));
// MylnOut( X, Y, map);
}
/* 領域開放 */
  free(map);
  map=NULL;
return 0;
//**************************************************************
//入力・表示
//**************************************************************
void MylnOut(int X,int Y,int *map)
{
  int i,j;
  for(j=0;j<Y;j++)
   for(i=0;i<X;i++) map[j*Y+i]=X;
  for(j=0;j<Y;j++){
   for(i=0;i<X;i++) printf("%3d",map[j*Y+i]);
   printf("\n");
  }
}

・コンパイルエラーは無く実行時エラーです。
.Borland C++ Compiler 5.5.1,TuboDebugger 5.5を使用しています。

A 回答 (4件)

VisualStudio2008ではとくに問題ありませんでしたよ。


return 0;の後に}は足しましたが・・・

とりあえず400000までは問題ありませんでしたよ。

GCC3.4.3でも問題ありませんでした。

コンパイラがおかしいか、他の部分では?

この回答への補足

<■VisualStudio2008ではとくに問題ありませんでしたよ。
・// MylnOut( X, Y, map);この部分(2箇所)をそのままでVisualStudio2008でTestした場合・・・・正常に表示されました。

・この部分を有効にした場合・・・「エラー表示」されます。

その後、絞り込みました。
・MylnOut( X, Y, map);この部分(2箇所)を有効にして
・入力・表示の下記の部分を無効にします
 //for(j=0;j<Y;j++)
 //  for(i=0;i<X;i++) map[j*Y+i]=X;
これで走らせると、正常に走ります。

・malloc(),realloc()で作成したメモリーは複数回の連続入力が出来ないのかも?

補足日時:2009/11/22 17:02
    • good
    • 0
この回答へのお礼

有難うございます。
■return 0;の後に}は足しましたが・・・
すいません、編集の時、誤って削除してしまいました。

お礼日時:2009/11/22 09:23

map=(int *)malloc(sizeof(X*Y));


は何をしているかわかりますか?
int1個分しかメモリ確保してませんよ。
普通は
map=(int *)malloc(sizeof(int)*X*Y);
と書きます。
さらに確保できたか調べるために、
if(NULL!=map){
fprintf(stderr,"確保できなかったよ。\n");
}
とか書きます。

n=400までは表示されていたのは”偶然”です。
偶然誰も使用していないメモリを使ってくれたのでしょう。

この回答への補足

有難うございます。
■map=(int *)malloc(sizeof(X*Y));の件
その通りでした・・・修正しました;

■if(NULL!=map){・・・の件
追加しました。

以上、ご指摘の箇所を修正した後、TESTしました。
・入力、表示の部分を無効にした場合、
従来と同じ様に正常に最後まで表示されます。

・有効にした場合、
・fprintf(stderr,"確保できなかったよ。\n");・は表示されません。
・n=3まで表示されて、従来の「エラー」が表示されます。

補足日時:2009/11/22 09:35
    • good
    • 0
この回答へのお礼

いろいろTestしてみましたが

・連続でmalloc/callocをするとエラーが数回後に表示されます。
・それで、領域変更の時は以前の領域を全部開放して、新規に得ています。

しばらくこれで行ってみます。

お礼日時:2009/12/06 08:59

ついでにいうと


map=(int *)realloc(map,sizeof(X*Y));
のように「realloc の第1引数に返り値を代入する」のは realloc でメモリが割り当てられなかったとき (= NULL が返るとき) に元の領域を取り戻すことができなくなってしまうのでよくありません.
tmp = realloc(map, sizeof(int)*X*Y);
if (tmp != NULL)
map = tmp;
のようにいったん別の変数で受けるべきです.
    • good
    • 0
この回答へのお礼

有難うございます。
■「realloc の第1引数に返り値を代入する」・・・・
・気にはしていたのですが、プログラムを簡素化してしました
・NULLに対応したコーテイングもしたのですが、一度も表示されなかったので、省いてしまいました。

お礼日時:2009/11/22 09:56

#2です。


if(NULL!=map){
fprintf(stderr,"確保できなかったよ。\n");
}
は間違いです。
if(NULL==map){
fprintf(stderr,"確保できなかったよ。\n");
return 1;
}
とかします。
    • good
    • 0
この回答へのお礼

有難うございます。
・ご指摘の件も含めて、色々TESTしてみます。
・あとで質問しますのでよろしくお願いします

お礼日時:2009/11/22 16:21

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報