• 締切済み

メモリの確保

C++で倒立振子のプログラムを書いている者です。 現在、思考回数を500でやらせるために、500の配列を用意してやっているのですが、この思考回数を500以上にすると、コンパイルは通るのですが、実行画面が出てすぐ消えてしまう現象が起こってします。おそらく、メモリが足りないのだと思い、mallocを試してみたのですが同じ現象が起きてしまいましい、どうようにして解決していいのかわかりません。宜しくお願い致します。

みんなの回答

  • sayakuma
  • ベストアンサー率0% (0/2)
回答No.4

#define MAX_STEPS 100000 typedef struct Data { double x, /* カート位置 */ x_dot, /* カート速度 */ theta, /* 柱角度、ラジアン */ theta_dot; /* 柱角速度 */ }DATA; DATA data[500][MAX_STEPS];/*思考回数*/ 変数detaのサイズは、sizeof(double)*4*500*MAX_STEPS =8*4*500*100000 = 1,600,000,000 およそ1.5GBとなります。 これだけの大きさの変数を32ビットのOSで 扱うのは一般的には無理でしょう。 巨大な配列に依存しないプログラムを考えたほうが 良いのではないかと思います。

suka19809876
質問者

お礼

ご回答ありがとうございます。 >巨大な配列に依存しないプログラムを考えたほうが 良いのではないかと思います。 確かに、おっしゃる通りです。 巨大な配列に依存しないプログラムを考えてみすます。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

どんな環境でプログラムを実行しているんでしょうか? プロセッサ, 搭載実メモリ量, コンパイラなどの情報がないとわからないのですが, 本当にメモリが足らない可能性はありますね.

suka19809876
質問者

補足

回答有難うございます。 使用しているのは学校のPCで、 Dell DIMENSION DIM4600C プロセッサは、Pentium(R)4 搭載実メモリ量は、512MB コンパイラは、Microsoft Visual Studio 6.0です。 宜しくお願い致します。

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

続き int get_box(double x,double x_dot,double theta,double theta_dot) { int box=0; if (x < -5.0 || x > 5.0 ||theta > 2*pai ||theta < -720*2*pai/360) return(-1); if (x < -2.0) box = 0; else if (x < 0.0) box = 1; else box = 2; if (x_dot < -1.5) ; else if (x_dot < 0.0) box += 3; else box += 6; if ((cos(theta) < 0.0) && (cos(theta) > -1.0) && (sin(theta) < 1.0) && (sin(theta) > 0.0)) box += 9; else if ((cos(theta) > -1.0) && (cos(theta) < 0.0) && (sin(theta) < 0.0) && (sin(theta) > -1.0)) box += 18; else if ((cos(theta) > 0.0) && (cos(theta) < 1/sqrt(2)) && (sin(theta) > -1.0) && (sin(theta) < -1/sqrt(2))) box += 27; else if ((cos(theta) > 1/sqrt(2)) && (cos(theta) < 2/sqrt(3)) && (sin(theta) > -1/sqrt(2)) && (sin(theta) < -1/2)) box += 36; else if ((cos(theta) > 2/sqrt(3)) && (cos(theta) < 0.965925826) && (sin(theta) > -1/2) && (sin(theta) < -0.258819045)) box += 45; else if ((cos(theta) > 0.965925826) && (cos(theta) < 1) && (sin(theta) > -0.258819045) && (sin(theta) < 0)) box += 54; // else if ((cos(theta) == 1.0) && (sin(theta) == 0.0)) box += 54; else if ((cos(theta) < 1.0) && (cos(theta) > 0.965925826) && (sin(theta) > 0)&&(sin(theta) < 0.258819045)) box += 63; else if ((cos(theta) < 0.965925826) && (cos(theta) > 2/sqrt(3)) && (sin(theta) > 0.258819045) && (sin(theta) < 1/2)) box += 72; else if ((cos(theta) < 2/sqrt(3)) && (cos(theta) > 1/sqrt(2)) && (sin(theta) > 1/2) && (sin(theta) < 1/sqrt(2))) box += 81; else if ((cos(theta) < 1/sqrt(2)) && (cos(theta) > 0.0) && (sin(theta) > 1/sqrt(2)) && (sin(theta) < 1.0)) box += 90; if (theta_dot < -2*pai) box += 99; else if ((theta_dot > -2*pai)&&(theta_dot < -pai)) box += 198; else if ((theta_dot > -pai)&&(theta_dot < -thirty_degrees)) box += 297; else if ((theta_dot > -thirty_degrees)&&(theta_dot < -twelve_degrees)) box += 396; else if ((theta_dot > -twelve_degrees)&&(theta_dot < 0)) box += 494; else if ((theta_dot > 0)&&(theta_dot < twelve_degrees)) box += 593; else if ((theta_dot > twelve_degrees)&&(theta_dot < thirty_degrees)) box += 692; else if ((theta_dot > thirty_degrees)&&(theta_dot < pai)) box += 791; else if ((theta_dot > pai)&&(theta_dot < 2*pai)) box += 890; else box+=989; return(box); } void init(void) { GLfloat light0_position[] = {0.0,0.0,1.0,0.0};/* 照明の位置 */ GLfloat light1_position[] ={100.0,100.0,0.0,1.0};/* 照明の位置 */ GLfloat light0_diffuse[] = {0.8,0.8,0.8,1.0};/* 拡散成分 */ GLfloat light1_diffuse[] = {0.5,0.5,0.5,1.0};/* 拡散成分 */ GLfloat light_specular[] = {0.2,0.2,0.2,1.0};/* 鏡面成分 */ GLfloat lmodel_ambient[] = {0.1,0.1,0.1,1.0};/* 環境光 */ glLightfv(GL_LIGHT0, GL_POSITION, light0_position); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); /* 照明No.1 */ glLightfv(GL_LIGHT1, GL_POSITION, light1_position); glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glDepthFunc(GL_LEQUAL); /*デプスバッファを有効化*/ glEnable(GL_DEPTH_TEST); } void display(void) { GLfloat material_color0[4] = {1.0,0.0,0.0,1.0}; GLfloat material_color1[4] = {0.0,1.0,0.0,1.0}; GLfloat material_color2[4] = {1.0,1.0,1.0,1.0}; GLfloat material_color3[4] = {1.0,1.0,0.0,1.0}; GLfloat material_specular[4] = {0.2,0.2,0.2,1.0}; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /*鏡面反射成分のセット*/ glMaterialfv(GL_FRONT, GL_SPECULAR, material_specular); /*初期設定*/ glTranslatef (0.0, 0.0, 0.0); /*台車*/ glMaterialfv(GL_FRONT, GL_DIFFUSE, material_color0); glMaterialf(GL_FRONT, GL_SHININESS, 10.0); glPushMatrix(); glTranslatef (0.0, 0.0, 0.0); glTranslatef (q, 0.0, r); glPushMatrix(); glScalef (0.8, 0.8, 0.5); glutSolidCube(1.0); glPopMatrix(); /*棒*/ //glPushMatrix(); glMaterialfv(GL_FRONT, GL_DIFFUSE, material_color1); glMaterialf(GL_FRONT, GL_SHININESS, 10.0); glTranslatef (0.0, 0.0, 0.0); /* 図形表示位置 */ glRotatef ((GLfloat) shoulder,0.0, 0.0, 1.0); glTranslatef (0.0, -1.4, 0.0); glPushMatrix(); glScalef (0.5, 2.9, 0.5); glutSolidCube(1.0); glPopMatrix(); glPopMatrix(); glutSwapBuffers(); } void reshape (int w, int h) { glViewport (10, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef (0.0, -1.0, -7.0); glRotatef (40, 1.0, 0.0, 0.0); } void keyboard (unsigned char key, int x, int y) { double z; static int i; z=0; switch (key){ case '3': if(success>0 && success<MAX_STEPS && data[trial-1][success].x == 0 && data[trial-1][success].x_dot ==0 && data[trial-1][success].theta ==0 && data[trial-1][success].theta_dot == 0){ q = data[trial-1][success-1].x; shoulder = -180-data[trial-1][success-1].theta/pai*180; glutPostRedisplay(); trial = trial+1; i = 0; break; } else{ q = data[trial-1][success].x; shoulder = -180 - data[trial-1][success].theta/pai*180; printf("theta=%lf,x=%lf,x_dot=%lf,theta_dot=%lf\n",data[trial-1][success].theta/pai*180, data[trial-1][success].x,data[trial-1][success].x_dot,data[trial-1][success].theta_dot); glutPostRedisplay(); if(i<MAX_STEPS){ success = success+1; } else{ trial = trial+1; success = 0; } break; } case 'x': printf("何回目?"); scanf("%d",&trial); success = 0; break; } } int main(int argc, char** argv) { int box,i,j; double x, x_dot, theta, theta_dot, failures; printf("学習率 ALPHA %.3f\n", ALPHA); printf("割引率 GAMMA %.3f\n", GAMMA); x = x_dot = theta_dot = 0; theta = 0; srand(time(NULL)); success = 0; trial = 0; failures = 0.0; // srand(RND_SEED); reset_controller(); for (i = 0; i < NUM_BOXES; i++)for (j = 0; j < 2; j++)q_val[i][j] = 0.0; /*初期化*/ while (success<MAX_STEPS) { if(first_time2==1){ first_time2=0; prev_state=get_box(x,x_dot,theta,theta_dot); // srand(time(NULL)); } else{ prev_state=box; // prev_action=cur_action; } prev_action=get_action(x, x_dot, theta, theta_dot); cart_pole(prev_action,&x,&x_dot,&theta,&theta_dot); box=get_box(x,x_dot,theta,theta_dot); data[trial][success].x = x; /*受け渡し*/ data[trial][success].x_dot = x_dot; data[trial][success].theta = theta; data[trial][success].theta_dot = theta_dot; if (box==-1) /*失敗*/ { failures=-1000.0; /*失敗時の報酬*/ Q_update(prev_state,box,prev_action,cur_action,failures); reset_controller(); x=x_dot=theta_dot=0;/*次の初期状態を設定*/ theta = 0; trial++; /*次のtrialへ*/ printf("At %d success ,try %d trials, %f\n",success,trial,data[trial-1][success-1].theta); /*結果を表示*/ success=0; /*成功success数を初期化*/ first_time2=1; if(trial>499){ printf("失敗\n"); return 0; // break; } } else{ /*1サクセス成功*/ if(cos(theta) > 0){ failures = (1+cos(theta)/2) ; } else if(cos(theta) < 0)failures = -1.0; cur_action = top_action(x, x_dot, theta, theta_dot); Q_update(prev_state,box,prev_action,cur_action,failures); // fprintf(fp2,"%lf\n",failures); // fprintf(fp2,"%lf\n",q_val[prev_state][prev_action]); success++; } } // for (i=0;i<NUM_BOXES;i++)fprintf(fp2,"%g %f\n",q_val[i][0],q_val[i][1]); printf("\n"); printf("%d回目でsuccess=%d回に達しました。\n",trial,success); printf("何回目?"); scanf("%d",&trial); glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (1000, 320); glutInitWindowPosition (100, 100); glutCreateWindow ("robot2"); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); // fclose(fp2); return 0; } int get_action(double x, double x_dot, double theta, double theta_dot) { double drand; drand = (double)rand() / (double)RAND_MAX; cur_state = get_box(x, x_dot, theta, theta_dot); /* どんな状態かをもらう*/ if (drand <= EPSILON){ /* 確率 EPSILON 以下ならランダム行動 */ action = rand()%2; } /* Now determine best action */ else if (q_val[cur_state][0] <= q_val[cur_state][1]){ action = 1; } else{ action = 0; } return action; } int top_action(double x, double x_dot, double theta, double theta_dot) { top_state = get_box(x, x_dot, theta, theta_dot); /* どんな状態かをもらう*/ /*次状態の報酬を観測する。*/ if (q_val[top_state][0] <= q_val[top_state][1]){ next_action = 1; } else{ next_action = 0; } return action; } void Q_update(int prev_state,int box,int prev_action,int cur_action,double failures) { double predicted_value; if (box == -1) predicted_value = 0.0; // else if (q_val[box][0] <= q_val[box][1]) else if(cur_action==1) predicted_value = q_val[box][1]; // else if(q_val[box][0] >= q_val[box][1]) else if(cur_action==0) predicted_value = q_val[box][0]; q_val[prev_state][prev_action] += ALPHA * (failures + GAMMA * predicted_value - q_val[prev_state][prev_action]); } void reset_controller(void) { cur_state = prev_state = 0; cur_action = prev_action = -1; }

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

どのようなプログラムですか? ソースを書いてくれないとなんとも言えません。(全部書く必要はありませんが)

suka19809876
質問者

補足

回答有難うございます。そうですよね。すいません。見づらいプログラムですが、宜しくお願い致します。 #include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> #include <GL/glut.h> #define NUM_BOXES 1088 /* 箱の数 */ #define MAX_STEPS 100000 /*ラジアン*/ #define one_degree 0.0174532 /* 2pi/360 */ #define six_degrees 0.1047192 #define twelve_degrees 0.2094384 #define twenty_degrees 0.3490658 #define thirty_degrees 0.5235987 #define fourty_degrees 0.6981315 #define fourty_five_degrees 0.785398 #define fifty_degrees 0.87266444 #define ninety_degrees 1.570796 #define one_hundred_eighty_degrees 3.141592 #define pai 3.1415926535 /*物理*/ #define GRAVITY 9.8 /*重力加速度*/ #define MASSCART 10.0 /*台車の質量*/ #define MASSPOLE 0.2 /*棒の質量*/ #define TOTAL_MASS (MASSPOLE + MASSCART) #define LENGTH 1.0 /* 棒の半分の長さ */ #define POLEMASS_LENGTH (MASSPOLE * LENGTH) //#define FORCE_MAG1 10.5 /*台車に加える力*/ #define FORCE_MAG2 100.0 /*台車に加える力*/ #define TAU 0.01 /* ステップ時間 */ #define FOURTHIRDS 1.3333333333333 /*変数*/ static double shoulder = 0, q = 0,r = 0; static int RND_SEED = 3; static double ALPHA = 0.1; /* 学習率 */ static double EPSILON=0.05; /* 探査率 */ static double GAMMA = 0.99; /* 割引率 */ static double q_val[NUM_BOXES][2]; static first_time1 = 1; static first_time2 = 1; static int cur_action, prev_action,action,next_action; static int cur_state, prev_state,top_state; unsigned long success,trial; void cart_pole(int,double*,double*,double*,double*); int get_action(double,double,double,double); int top_action(double,double,double,double); int get_box(double, double, double, double); void Q_update(int,int,int,int,double); void reset_controller(void); double noise(); typedef struct Data { double x, /* カート位置 */ x_dot, /* カート速度 */ theta, /* 柱角度、ラジアン */ theta_dot; /* 柱角速度 */ }DATA; DATA data[500][MAX_STEPS];/*思考回数*/ void cart_pole(int prev_action,double *x,double *x_dot,double *theta,double *theta_dot) { double xacc,thetaacc,force,costheta,sintheta,temp; force = (prev_action > 0)? FORCE_MAG2 : -FORCE_MAG2; costheta = cos(*theta); sintheta = sin(*theta); temp = (-force - (MASSPOLE * POLEMASS_LENGTH * *theta_dot * *theta_dot * sintheta)) / TOTAL_MASS; thetaacc = (GRAVITY * sintheta + costheta * temp) / (LENGTH * (FOURTHIRDS - MASSPOLE * costheta * costheta / TOTAL_MASS)); xacc = (force + MASSPOLE * POLEMASS_LENGTH * (*theta_dot * *theta_dot * sintheta - thetaacc * costheta)) / TOTAL_MASS; /*** Update the four state variables, using Euler's method. ***/ *x += TAU * *x_dot; *x_dot += TAU * xacc; *theta += TAU * *theta_dot; *theta_dot += TAU * thetaacc; }

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • メモリ確保方法を教えてください。

    Visual Studio.NET でC言語でプログラムを組んでいるのですが、二次元配列をたくさん使用したプログラムで、コンパイルして実行しようとするとエラーが表示されてしまいます。配列の要素を少なくすると実行はされるのですが、要素数が多くなるとエラーが表示されます。 実行時にユーザの使用メモリ数が制限されているなら、その使用メモリを増やす方法があれば教えていただけませんか?よろしくお願いします。

  • 配列の操作やメモリの確保のミスについて

    プログラミング初心者です。 Visal Studio 2010を使用してC++の勉強をしています。 配列の操作やメモリの確保でエラーを起こした場合、OSや他のプログラムにもエラーを引き起こすことがあるのでしょうか? (記述・実行しているプログラムは教材に記されているただのコンソールアプリです。複雑であったり大規模なものではありません。) たとえば、mallocで配列のメモリを確保したが、その配列の要素数以上に値を書き込んだり参照したり、freeをし忘れたりした場合です。 その時、想定していないメモリ領域に値が書き込まれることで、他のプログラムが壊れたりするんじゃないかと心配です。 というのも、配列の操作やmallocを失敗したときに、パソコンの動作が不安定になるのです。(画面がちらついたり、表示がおかしくなる。) explorer.exeを再起動するだけで収まるように見えるのですが、何が起きているのか不思議です。 以上になります。長文お読みいただきありがとうございました。 よろしくお願いいたします。

  • malloc関数によるメモリの確保

    C初心者です。 malloc関数によるメモリの確保に関して教えてください。 2次元配列のサイズに対してmalloc関数の引数値をたとえば、 (double*)malloc(datasize*sizeof(double)) などとしメモリ領域を確保すると、メモリアドレスはデータのサイズ によらず一定 1234044、1234048となります。 データサイズを大きくし、datasize*sizeof(double)が16Kバイトを超えるとcmd.exeがエラーとなり落ちます。 デバックモードで実行すると 「"System.AccessViolationException"のハンドルされていない例外が不明なモジュールです。で発生しました。 追加情報:保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリがこわれていることが考えられます」 というメッセージがでます。 コンパイラはExpressEdition2008です。 この現象を回避するにはどうすべきか、なぜこのようなことが起こるのかご教授ください。 よろしくお願いいたします。

  • アドレス格納のための二次元配列のメモリ動的確保

    アドレス格納のための二次元配列のメモリ動的確保 二次元配列のためにメモリを動的確保しなければならないのですが、 その配列に格納したいものが 「DATA型のポインタ」です。(DATA型はtypedefした構造体です。) プログラム実行中にmallocで確保した、数あるDATA型の構造体の、その先頭アドレスを リストアップするための配列です。 この場合、どのような形でmallocすればよいのでしょうか? 教えていただけるとありがたいです。よろしくお願いいたします。 -- たとえば m×n のint型の配列は、 ◆ int *i; ◆ i = (int *)malloc( m * n * sizeof(int) ); となりますよね。 この要領がでやるのが一般的にわかりやすいものだとするならその方法でやりたい (後発の人が自分のソースコードを読む可能性があるため)のです。 -- 同様にm×nの「DATA型のポインタを格納するための二次元配列」を動的確保したい場合、 ◆ DATA *d; ◆ d = (DATA *)malloc( m * n * sizeof(DATA) ); この文にどのように付け加えたら良いのでしょう? もうあと一歩な気がするのですが(笑)。しかし参考書等で勉強しましたがわかりませんでした・・・。 わかる方、どなたかよろしくお願いいたしますm(_ _)m あとこれだけ通ればコンパイルが通るんです!!!!! たぶん(笑)

  • メモリ確保の謎。

    C言語のメモリの確保の所でふと疑問に思ったのですが、 malloc,calloc,realloc,memset,memcpyなどの関数を使うときって #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <malloc.h> とか書かないといけないと本にはありますが、#include <stdio.h>だけで なんのエラーにもならずに実行できてしまうのはなぜでしょうか? 実際のプログラムにはmallocとreallocしか使ってないのですが、#include <stdio.h>でできてしまいます。 でも教科書には他にも書かなきゃいけないとかいてありますが、なぜ書かなくても実行できてしまうのでしょうか?

  • VBで動的なメモリの確保

    VBでCのmallocのように動的なメモリ確保はどうやってするのでしょうか? 具体的にはstring型をn個用意したいのです。

  • 2次元配列を確保したいのですが、

    2次元配列を確保したいのですが、 size of array 'buf' is too large というエラーで確保できません。 mallocを使って確保しようとしましたが、コンパイルできましたが、 実行するとメモリ確保に失敗します。 大きな2次元配列を確保する方法を教えてください。

  • C言語 動的なメモリの確保 実行できない

    malloc関数を使いメモリを確保しそこへ"ABCD"と記憶させ、ポインタ*Cを使い確保したメモリの内容を表示するプログラムです。 ********************************************* #include <stdio.h> #include <stdlib.h> int main(void) {   int i;   char *C;   C = (char *) malloc (sizeof(char) * 5);   C = "ABCD";   for(i = 0; i < 5; i++){     if(C[i] != NULL){       printf("%s", C[i]);    ←※エラー※     }   }   free(C);   return 0; } ********************************************* 正常にコンパイルできますが実行エラーになります。VCを使いF10のデバッグテストで※のところエラーになります。なぜなのでしょうか?

  • C++ 最適なメモリ確保

    画像処理をするために実験的にC++でプログラムを書いています。 malloc関数でBMP画像の画素位置を、画像画素分確保するだけのint型配列を作成するにはどうしたらよいでしょうか。 因みに、入力画像の解像度は640x480です。 一番左下の画素を(x,y)=(0,0)として考えています。 ある条件の画素に該当する画素座標を、下のStackX,StackYにx,y成分ごとに格納していくものです。 //////// int *StackX = (int *)malloc(sizeof(int)*100000); int *StackY = (int *)malloc(sizeof(int)*100000); //////// 上のように書くと、途中でクラッシュしてしまいます。 ですが、大目にメモリをとって //////// int *StackX = (int *)malloc(sizeof(int)*10000000); int *StackY = (int *)malloc(sizeof(int)*10000000); //////// で実行すると、最後まで動いてくれます。

  • C言語 メモリ?

    最近、C言語の勉強を始めているものです。 gccでコンパイルし、実行ファイルを実行すると 強制終了 と表示されます。 gdbで実行してみると、 Program terminated with signal SIGKILL, Killed. The program no longer exists. You can't do that without a process to debug. と表示されました。 プログラムの中で、二次元配列 a[10000][10000],b[10000][10000] というような大きい配列を使っているのが原因なのかなと思っていますが、どうなんでしょうか?mallocでメモリを確保したらいいのでしょうか? ソースを載せることができなく申し訳ないですが、よろしくお願いします。