自分のお店を開く時の心構えとは? >>

int CYCL;
int DCYCL=100;
int ttime=2000;
int t;

main(){

while(CYCL<=DCYCL){

for(t=0;t<=ttime;t++){

..........................
if(CYCL==DCYCL){
.................

}
if(CYCL==DCYCL){
.................

}

.........................

}

CYCL++;

}

}

のようなプログラムを作っています。しかしなぜかttimeに-23878728というような
よくわからない値が代入されているというエラーが起きていることに気づきました。
そこでprintfを用いて以下のようにエラー場所の探索を行いました。

main(){

while(CYCL<=DCYCL){

for(t=0;t<=ttime;t++){

..........................
printf("a ttime=%d\n",ttime);
if(CYCL==DCYCL){
.................
printf("b ttime=%d\n",ttime);

}
if(CYCL==DCYCL){
printf("c ttime=%d\n",ttime);
.................
printf("d ttime=%d\n",ttime);

}

.........................

}

CYCL++;

}

}

するとprintf("c DCYCL=%d\n",DCYCL);とprintf("d DCYCL=%d\n",DCYCL);
の間のどこかにあることがわかりました。
出力結果は
a ttime=2000
b ttime=2000
c ttime=3000
d ttime=-2382272
そこでprintf("a ttime=%d\n",ttime);をけしてプログラムをまわしたところ
b ttime=2000
c ttime=-2382272
d ttime=-2382272
というふうにprintfをはさむことで値が変わってしまうようになってしまいました。

この問題はどうすれば解消できるのでしょうか?
もとのプログラムを張りたいのですが、10000行近くあり、張ることが出来ません。
またttimeに値を代入するようなことは始めの宣言時以外一切やっていません。

どなたかご教授お願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

既に回答のあるように、メモリーリークが発生しているのだとは思いますが、その原因は省略されたところにあります。


よって、これだけではどこを治せばよいかは言えません。


あとは、プログラム構成がよくないので、間違いを見付けにくい、というのがあるかもしれません。
もし、 ここにあるのがプログラムの全体だとしたら、 1万行近い main関数なんて考えたくありません。

定数として使っている(と思われる) ttime,DCYCLはともかく、ループカウンタのtや,なにかの計算をするCYCLまでグローバル変数にしてしまっているのも、最近の書き方ではありません。
戻り値も引数も省略した main(){...}という書き方は、現在では使いません。

> main(){
> while(CYCL<=DCYCL){
実際にこの間になにも記述が無いのなら、CYCLの初期化がありません。
グローバル変数にしたことで、たまたま0になっていますが、それを期待して明示的に初期化しないのは思わぬバグの元になります。
明示的に初期化するようにしましょう。
    • good
    • 0
この回答へのお礼

お礼が遅くなりました。
無事解決いたしました。

変数を定義していない個所に
代入をしようとしたため、エラーだったようです。

ありがとうございます。

お礼日時:2011/01/23 00:08

メモリ破壊のパターンです。


printfを入れたことにより変数等のメモリ配置が変わったために正しく動作するように見えるだけです。
検出されたのがこの変数であり、他にもある可能性があります。メモリ転送関係(ポインタ等)の全面的な見直しが必要と考えます。
このようなケースではコンパイルオプションの変更でも発現することがあります。
    • good
    • 0

配列確保領域以外の書き換えやポインタのアドレス(オフセット)計算の間違いなどで ttimeの領域を壊しているのかも知れないですね



とりあえず ttimeを初回の代入だけで済むなら

const int ttime = 2000;
などと 定数扱いにしてしまうとかでしょうか ・・・
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q変数の値が勝手に変化する原因

以下のようなプログラムを書きました。(一部省略)
data2[8] = '\0'; の行が実行された後になぜかgの値が1から0に変化してしまいました。
勝手に変数の値が変化しており、原因が把握できていません。
この原因として考えられることがあれば教えていただけないでしょうか?
よろしくお願いします

以下、書いたプログラムです。

char data2[8];
FILE* fp;
int g;

int main{

fread(data2,8,1,fp);
data2[8] = '\0';    ←ここでgの値が変化します。

fread(data2,8,1,fp);
data2[8] = '\0';

return 0;
}

Aベストアンサー

> char data2[8];
と宣言したら、
data2[0]~data2[7]
までの8個が確保されます。

data2[8]にアクセスした場合の結果はどうなるかわかりません。

他の言語では、範囲外エラーになったり、自動で拡張されたりするのですが、Cではその様な処理を行いません。
添字の範囲の管理はプログラマの責任です。

以上、C言語の基本です。忘れないでくさい。

Q変数の内容がコロコロ変わる、原因を教えてください。

VC++2010でプログラムしていますが、下記変数TESTの内容がプログラム実行中にある時点で勝手に変更されてしまいます。もちろんプログラム中に変数TESTを変更する記述は何処にも書いていません。
64bit環境での変数設定の注意点を教えてください。


long TEST=0;
long TEST1;
char LOOP=1;

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
while(LOOP)
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );//翻訳する
DispatchMessage( &msg );//急送する
}

TEST1 = 7777777;

if(TEST)Beep(3000,100);

}//while(LOOP)

return msg.wParam;
}//WinMain

VC++2010でプログラムしていますが、下記変数TESTの内容がプログラム実行中にある時点で勝手に変更されてしまいます。もちろんプログラム中に変数TESTを変更する記述は何処にも書いていません。
64bit環境での変数設定の注意点を教えてください。


long TEST=0;
long TEST1;
char LOOP=1;

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
while(LOOP)
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
Transla...続きを読む

Aベストアンサー

>コンパイラによりバグをはじき出す基準が変わるのでしょうか?バグが潜んでいるのならNO3の方の回答が考えられそうですが、この場合アクセス違反でも起きない限り発見も難しいと考えます。

その難しいことが起きるから発見されないんですけどね。
世の中の製品のゲームやアプリでも偶然動いていることは良く有ります。
コンパイラが変わるとコンパイラの最適化アルゴリズムが変わるので変数のメモリの配置やコンパイル後の機械語命令コードの並びそのものが完全に変わるのはよく有る出来事です。そのため前のコンパイラでは問題なかったプログラムがいきなりバグだらけのプログラムに変わることがあります。

>ついでに教えて頂きたいのですが、ちなみにバグの潜んだVC++6でビルドした実行ファイルは開発環境では完動しても、他のマシンで不具合が起きる事もあるのでしょうか?教えてください。

Releaseビルドした上で開発マシンでバグが出なかった場合は、操作方法や稼働負荷で出るバグでない限りバグが表面化する可能性は限りなく低いと思います。
つまり、他のPCやバージョンの違うOSで動く可能性はかなり高いです。と言ってもOSがWin98からWinXPに変わったときにバグが表面化したソフトも実際にかなり有りましたけどね。

>コンパイラによりバグをはじき出す基準が変わるのでしょうか?バグが潜んでいるのならNO3の方の回答が考えられそうですが、この場合アクセス違反でも起きない限り発見も難しいと考えます。

その難しいことが起きるから発見されないんですけどね。
世の中の製品のゲームやアプリでも偶然動いていることは良く有ります。
コンパイラが変わるとコンパイラの最適化アルゴリズムが変わるので変数のメモリの配置やコンパイル後の機械語命令コードの並びそのものが完全に変わるのはよく有る出来事です。そのため前のコ...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

QprintfでSegmentation fault

gccでプログラムを作っています。
分割コンパイルを試していたのですが、
printf("a");
なら正常なのに、
i=1;
printf("%d",i);
とするとSegmentation faultになります。
printf("%f",0.1);
とかも無理です。
分かる方がいらっしゃいましたらお願いします。

Aベストアンサー

「かなり省略」の部分が重要だと思います。

スタックフレームを破壊している可能性があります。

main, a, bのいずれかの関数でローカルな配列を使っているなら、ためしに配列のサイズを必要量の何倍かに拡大してみてください。これによって症状がなくなるか緩和されるのであれば、配列の上限を超えて書き換えているということになります。

場合によってはprintfの後で落ちているという可能性もあります。なぜなら、printfは、改行が与えられない限り短い文字列はバッファに溜まるだけで、直後でSEGVした場合は画面に反映されないためです。

コメントアウトしたら大丈夫だからprintfのせいだとは限りません。その有無によってスタックフレームの構成が最適化されて、たまたま落ちないだけかもしれません。

Qprintf で二進表示を行いたい。

すみません。教えていただきたいことがあります。
printf で普通のintの値をフォーマット指定子を使用して二進表示をしたかったのですが見当たりませんでした。
どうにかintの内容を二進で確認したいのですが、どのようにすれば良いですか?
宜しくお願いします。

Aベストアンサー

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if ( value & bit ){
  putchar('1');
 }
 else{
  putchar('0');
 }
}
printf( " です。\n" );

最後に:
・1バイトが 8 ビットの環境が前提です。→まぁ、普通は 8 ビットですが…。
・上記のサンプルを関数などにすれば使いやすくなります。→print_bin()など
・以上。おわり。

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if...続きを読む

QC言語のポインターに関する警告

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int=i; /*main関数内のfor文で使用*/
char line[100], out[100];
void change(int);

/*関数*/
void change(int i)
  {
   if(line[i]=='1'){
    out[10]="a\0"
   }if(line[i]=='2'){
    out[10]="b\0";
   }if(line[i]=='3'){
    out[10]="c\0"
}
}

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int...続きを読む

Aベストアンサー

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(line[i]=='1'){
    out[10]=0x61; /* aのASCIIコード */
   }if(line[i]=='2'){
    out[10]=0x62; /* bのASCIIコード */
   }if(line[i]=='3'){
    out[10]=0x63; /* cのASCIIコード */
}
}
と書きましょう。

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(l...続きを読む

Q構造体の各データの表示について以下のようなプログラムを作成しました。

構造体の各データの表示について以下のようなプログラムを作成しました。

#include <stdio.h>

struct tb{
char name[20];
char sex;
int age;
double height;
double weight;
};

int main(void)
{
int i;

struct tb test[2];

test[0].name="amada"
test[0].sex='f';
test[0].age=20;
test[0].height=172.5;
test[0].weight=62.5;

test[1].name="okada";
test[1].sex='f';
test[1].age=21;
test[1].height=180.2;
test[1].weight=70.8;

for(i=0; i<2; i++){
printf("%s %s %d %f %f \n",test[i].name,test[i].sex,test[i].age,test[i].height,test[i].weight);
}

return 0;
}

ファイル名を適当にsample.cとしてgcc sample.c した所、以下のようなコンパイルエラーが出ました。

sample.c: In function ‘main’:
sample.c:18: error: incompatible types when assigning to type ‘char[20]’ from type ‘char *’
sample.c:18: error: expected ‘;’ before ‘test’
sample.c:23: error: incompatible types when assigning to type ‘char[20]’ from type ‘char *’

このエラーを元にソースをどのように修正したらよいか教えて頂けますでしょうか?
よろしくお願いいたします。

構造体の各データの表示について以下のようなプログラムを作成しました。

#include <stdio.h>

struct tb{
char name[20];
char sex;
int age;
double height;
double weight;
};

int main(void)
{
int i;

struct tb test[2];

test[0].name="amada"
test[0].sex='f';
test[0].age=20;
test[0].height=172.5;
test[0].weight=62.5;

test[1].name="okada";
test[1].sex='f';
test[1].age=21;
test[1].height=180.2;
test[1].weight=70.8;...続きを読む

Aベストアンサー

エラーメッセージに書いてある通り
構造体を以下のように定義するか
struct tb{
char name[20]; -> char *name
char sex;
int age;
double height;
double weight;
};

#include <string.h>
を追加して
strcpy(test[0].name,"amada");
にするかのいずれか(後者の方がいいと思うけどね)

あとは
>test[0].name="amada"
文末に;が無いね。

Qlong doubleの表示方法

long doubleの型を使いたいのですが、出力するとき、

printf("%e\n", A);

とすると、8桁しか出力されません。
これを16桁まで出力させる方法はないでしょうか。

Aベストアンサー

long doubleのときは、eの代わりにLeを使います。

long doubleがサポートされていたとしても、精度はまちまちです。doubleと全く同じ場合もあるでしょうし、80ビットや128ビットであることもあります。
printf("%d, %d\n", sizeof(double), sizeof(long double));
のように確認してみれば、使う意味があるかどうかはわかります。

doubleの精度は15桁なので、微妙なところですね。

Qセグメンテーション違反

C言語を使用しています。

構造体に値をいれようとしたら、コンパイルは出来るのですが、実行時に
「セグメンテーション違反です (core dumped)」
となってしまい、それ以上行えません。

構造体と代入したい変数との型は、合っています。

いろいろ本などで見ましたが、何が原因かわからず困っています。
教えてください。
宜しくお願いします。

Aベストアンサー

OSは何でしょうか。コンパイラは何を使用していますか?
通常、デバッグオプションをつけて実行すると、異常の発生したソースの箇所で止まりますので、それが手がかりになります。またNo1の方が言われてますように、ソースが公開できるのであれば、ソースを提示するのが良いかと思います。


人気Q&Aランキング

おすすめ情報