データ数を増やすとエラーになる理由とは?

このQ&Aのポイント
  • プログラムでデータ数を増やすとエラーが発生する理由を教えてください。
  • データ数を増やすとプログラムが正常に動作しない理由について知りたいです。
  • データ数を増やすとプログラムがエラーになる原因について教えてください。
回答を見る
  • ベストアンサー

データ数を増やすとエラーになる

typedef struct DATA{ int data; struct DATA *left; struct DATA *right; }node,*tree; tree makenode(int data) {     tree q;     if((q=(tree)malloc(sizeof(node)))==NULL){        printf("メモリ割り当てエラー\n");        exit(-1);     } q->left=NULL; q->right=NULL; q->data=data;   return q; } をつくり、for文でまわしながら、処理を行うプログラムにしたいんですが、まわす回数が4までだときちんと動くのですが5以上にすると エラーになってしまいます。なぜエラーになるか全くわかりません。 わかる方教えてください。お願いします。

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

  • ベストアンサー
  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.4

バグが原因でstackを破壊しているときは、バグとは一見無関係のところでエラーが発生します。デバッガーで1ステップずつ追うか、もうちょっと広い範囲のソースを載せてみてください。

inayou
質問者

お礼

ご指摘の通り、広い範囲で見直したら、間違っていたところが見つかりました。mallocでデータ数ぶんだけとるつもりが1つだけしか領域をとってませんでした。 回答ありがとうございました。

その他の回答 (3)

回答No.3

#1です。 さらにループ回数を増やした所、 11,080,000~11,090,000回程度繰り返した所でメモリが足りなくなりました。 とりあえず、ソース乗せときます。 #include <stdio.h> #include <stdlib.h> typedef struct DATA{ int data; struct DATA *left; struct DATA *right; }node,*tree; tree makenode(int data) { tree q; if((q=(tree)malloc(sizeof(node)))==NULL){ printf("メモリ割り当てエラー(%d)\n",data); system("pause>NUL"); exit(-1); } q->left=NULL; q->right=NULL; q->data=data; return q; } int main() { int i,j; tree dmm[10000]; for( j=0;j<10000;j++) { printf("start[%d]\n",j); for( i=0;i<10000;i++) { // printf("start[%d]\n",i); dmm[i] = makenode(i); } } printf("正常\n"); system("pause>NUL"); return 0; } system("pause>NUL")は、そこでキー入力があるまで一旦停止させるためのものです。 エラーの原因としては、 1)繰り返すfor()の方に問題があるかもしれない。 2)実行環境のせいかもしれない。 程度までしかわかりません。 デバッグ用のログの入れ方ですが、もし現状で if((q=(tree)malloc(sizeof(node)))==NULL){ // ログ1 … } // ログ2 と入れている場合には、 // ログ1 q=(tree)malloc(sizeof(node)); // ログ2 if(q==NULL){ // ログ3 … } // ログ4 と入れてみてください。もしかしたら何かわかるかもしれません。

inayou
質問者

お礼

違うところでのバグのせいでした。 回答ありがとうございました

inayou
質問者

補足

回答ありがとうございます。 やはりループ回数を5以上にすると、 1回目のループのログ2が出ません。 4以下ではちゃんと出るのになぜ? っていう感じです。

  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.2

下記の通り100000回まわしてもエラーになりませんでした。エラーはほかの部分にあるのではないでしょうか? またどのようなエラーが返っているのか明記してください。 #include <stdio.h> #include <stdlib.h> typedef struct DATA { int data; struct DATA *left; struct DATA *right; } node , *tree; tree makenode(int data) { tree q; if ((q = (tree) malloc(sizeof(node))) == NULL) { printf("メモリ割り当てエラー\n"); exit(-1); } q->left = NULL; q->right = NULL; q->data = data; return q; } int main(void) { int i; for (i = 0; i < 100000; i++) { makenode(i); printf("%d\n",i); } return 0; }

inayou
質問者

お礼

違うところでのバグのせいでした。 回答ありがとうございました

inayou
質問者

補足

回答ありがとうございます そのプログラムでは、ちゃんと動くのに、作ろうとしているものでは やはりエラーが出てしまいます。

回答No.1

「エラーになる」とは、どういう状況ですか? エラー吐いて強制終了?malloc()が失敗するだけ? コピペして、for()で回す用にmain()を補充し、手元で動かしてみましたが、 for()で100回繰り返してもエラーは発生しませんでした。 何処か他に問題はありませんか?

inayou
質問者

補足

エラーは 「問題が発生したため<プログラム名>を終了します」 とでて、エラーを送信しますかというものがでます。 プログラムの間にprintfを使ってどこまで実行されているかを調べたら makenode関数内のmallocでした(mallocの後のprintfが表示されないで終了)。なぜでしょうか?

関連するQ&A

  • (構造体)双方向連結リストの作成!

    ダミーノードを先頭に、双方向連結リストを作成したいのですがなかなかうまくできません。とりあえず、ダミーノード無しのものはなんとか出来ましたが、循環連結がうまくいっていない次第です。 どうかお力添え願います。 #include<stdio.h> #include<malloc.h> #include<process.h> typedef struct node{ struct node *left; char name[20]; int age; struct node *right; }NODE; NODE *memalloc(void); void main(void) { NODE *head, *tail, *p; tail = NULL; while(p = memalloc(), printf("名前 年齢入力(Ctrl + Zで終了)>"), scanf("%s %d", p -> name, &p -> age) != EOF){ p -> left = tail; tail = p; } p = tail; head = NULL; while(p != NULL){ p -> right = head; head = p; p = p -> left; } head -> left = tail; p = head; printf("リスト表示\n"); while(p != NULL){ printf("名前:%20s 年齢:%5d\n", p -> name, p -> age); p = p -> right; } } NODE *memalloc(void) { NODE *ptr; if((ptr = (NODE *)malloc(sizeof(NODE))) != NULL){ return ptr; } printf("\n動的メモリ割当に失敗しました。\n"); exit(1); return 0; }

  • C言語でセグメンテーションエラー

    環境はUbuntu Feisty Fawn gcc 4.1.2 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 32 #define DEBUG struct node{ char *moji; struct node *left,*right; }; typedef struct node NODE; void error(char *msg){ fflush(stdout); fprintf(stderr, "%s\n", msg); exit(1); } NODE *createNode(char *x){ NODE *new; new = malloc(sizeof(NODE)); if(new == NULL){ error("メモリがありません。\n"); } new->moji = x; new->left = NULL; new->right = NULL; return new; } NODE *insertNode(NODE *p, char *x){ if(p == NULL){ p = createNode(x); }else if(strcmp(p->moji, x) == 0){ return NULL; }else if(strcmp(p->moji, x) > 0){ p->left = insertNode(p->left, x); }else{ p->right = insertNode(p->right, x); } return p; } void printTree(NODE *p){ if(p == NULL) return; printTree(p->left); printf("%s\n",p->moji); printTree(p->right); } int main(int argc, char *argv[]){ FILE *fp; char *buf = malloc(sizeof(char) * MAX); char *ans = malloc(sizeof(char) * MAX); NODE *p = malloc(sizeof(NODE)); if( argc > 2 ){ printf("ファイルの指定は一つだけです。\n"); return -1; }else if(argc == 1){ printf("ファイルを指定してください。\n"); return -1; } fp = fopen( argv[1] , "r" ); if( fp == NULL ){ printf("ファイル読み込みに失敗しました。\n"); return -1; } while(fscanf(fp,"%s",buf) == 1){ ans = strtok(buf," -,."); p = insertNode(p, ans); while(ans != NULL){ ans = strtok(NULL," -,."); if(ans != NULL){ p = insertNode(p, ans); } } } printTree(p); fclose(fp); return 0; } このファイルを読み込んで記憶させたいんです。 file.txt ここから下がファイルの中身 The Java programming language is a general-purpose, concurrent, class-based, object-oriented language. It is designed to be simple enough that many programmers can achieve fluency in the language. どこがいけないとおもいますか?

  • 二進検索木

    下記のプラグラムで二進検索木を作りたいのですが、うまくいきません(2つまでしか保存ができない)。 たぶん、ポインタがおかしいと思うのですが・・・。お願いします。 入力 年齢 1 名前 a メアド a@ 年齢 2 名前 b メアド b@ 年齢 3 名前 c メアド c@ 年齢 -1 出力 b  ×  c   ×   × 歳 2 名前 b メアド b@ 歳 3 名前 c メアド c@ #include<stdio.h> #include<stdlib.h> struct node{ char *name; char *email; int age; struct node *left; struct node *right; }; void getline(char *s,int n){ int c; while(--n>0&&((c=getchar())!=EOF && c!='\n')) *s++=c; *s='\0'; } char* dupstr(char* strg){ char* newstr; newstr = (char*)malloc(sizeof(char)*strlen(strg)); strcpy(newstr,strg); return newstr; } struct node *new(int n,char *na,char *em){ struct node *p; p=malloc(sizeof(struct node)); p->age=n; p->name=na; p->email=em; p->left=NULL; p->right=NULL; return p; } void print(struct node *p){ if(p==NULL)return; else{ print(p->left); printf("\n歳:%d ", p->age); printf("\n名前:%s ", p->name); printf("\nメアド:%s ", p->email); print(p->right); } } void print_tree(struct node *p,int level){ int i; for(i=0;i<level;i++)printf(" "); if(p==NULL)printf("×\n"); else{ printf("%s\n",p->name); print_tree(p->left,level+1); print_tree(p->right,level+1); } } void *insert(struct node *p,int n,char *na,char *em){ int c; c=strcmp(p->name,na); if(c==0); else if(c>0){ if(p->left==NULL) {p->left=new(n,na,em); return p;} else insert(p->left,n,na,em); } else{ if(p->right==NULL){ p->right=new(n,na,em); return p;} else insert(p->right,n,na,em); } } main() { int age,g; char buf[80],a[80],b[80],*email,*name; struct node *root=NULL; g=1; printf("\n歳を入力:"); getline(buf,sizeof(buf)); printf("\n名前入力:"); getline(a,sizeof(a)); name=dupstr(a); age=atoi(dupstr(buf)); printf("\nメアド入力:"); getline(b,sizeof(b)); email=dupstr(b); root=new(age,name,email); while(g==1){ printf("\n歳を入力:"); getline(buf,sizeof(buf)); age=atoi(dupstr(buf)); if(age==-1) break; printf("\n名前入力:"); getline(a,sizeof(a)); name=dupstr(a); printf("\nメアド入力:"); getline(b,sizeof(b)); email=dupstr(b); root=insert(root,age,name,email); } print_tree(root,0); print(root); }

  • 2分木のノードの指定方法を変えたい

    下のプログラムはコマンドライン引数できまった形で入力した数を2分木にしてそれを表示させるc言語のプログラムです。 きまった形というのは 短縮形は [ 8 [ 7 2 5 ] [ 3 1 _ ] ] 短縮形でないのは [ 8 [ 7 [ 2 _ _ ] [ 5 _ _ ] ] [ 3 [ 1 _ _ ] _ ] ] ] のような形で、実行結果はそれぞれ a.exe [ 8 [ 7 2 5 ] [ 3 1 _ ] ] 入力データ [ 8 [ 7 2 5 ] [ 3 1 _ ] ] a.exe [ 8 [ 7 [ 2 _ _ ] [ 5 _ _ ] ] [ 3 [ 1 _ _ ] _ ] ] ] 入力データ [ 8 [ 7 2 5 ] [ 3 1 _ ] ] のようになります。 これをこのような形ではなくコマンドラインで 8 7 3 2 5 1 と入力するだけで2分木になるように 下のプログラムを変えたいのです。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef int BITREE_TYPE; /* 格納データの型 */ struct node { BITREE_TYPE value; /* ノードの値 */ struct node *left; /* 左ノードのアドレス */ struct node *right; /* 右ノードのアドレス */ }; typedef struct node BITREE_NODE; void error(char *msg); BITREE_NODE *createNode(BITREE_TYPE x); void destroyBITree(BITREE_NODE *p); int isLeafNode(BITREE_NODE *p); void printBITree(BITREE_NODE *p, int tabs, int brief); BITREE_NODE *inputBITree(char *str[], int len, int *end); int gShortFormat = 1; /*1ならば短縮形で出力する*/ void error(char *msg){ fflush(stdout); fprintf(stderr,"%s\n", msg); exit(1); } BITREE_NODE *createNode(BITREE_TYPE x){ BITREE_NODE *new; new = malloc(sizeof(struct node)); if(new == NULL) error("createNode: メモリがありません"); new->value = x; new->left = NULL; new->right = NULL; return new; } void destroyBITree(BITREE_NODE *p){ if(p == NULL) return; destroyBITree(p->left); destroyBITree(p->right); memset(p, 0, sizeof(struct node)); free(p); } int isLeafNode(BITREE_NODE *p){ return(p->left == NULL) && (p->right == NULL); } void printSubtree(BITREE_NODE *p){ if(p == NULL){ printf("_"); return; } if(gShortFormat != 0 && isLeafNode(p)){ printf("%d", p->value); } else{ printf("[ "); printf("%d ", p->value); printSubtree(p->left); printf(" "); printSubtree(p->right); printf(" ]"); } } void printBITree(BITREE_NODE *p, int tabs, int brief){ int i; gShortFormat = brief; for (i = 0; i<tabs; i++) printf("\t"); printSubtree(p); printf("\n");fflush(stdout); } BITREE_NODE *inputBITree(char *str[], int len, int *end){ BITREE_NODE *p; int i =0; if(len < 1) error("inputBITree:データがありません"); /*短縮形の処理*/ if(strcmp(str[0], "[") != 0){ if(strcmp(str[0], "_") == 0) error("inputBTITree:値に_は指定できません"); *end =1; return createNode(atoi(str[0])); } p = createNode(atoi(str[1])); i = 2; if(strcmp(str[i], "_") != 0){ p->left = inputBITree(&str[i], len -i, end); i+= *end; } else{ i++; } if(strcmp(str[i], "_") != 0){ p->right = inputBITree(&str[i], len -i, end); i+= *end; } else{ i++; } if(strcmp(str[i], "]") != 0) error("inputBITree: 入力データが]で終わっていません"); *end = i + 1; return p; } int main(int argc, char *argv[]){ BITREE_NODE *p; int end = 0; p = inputBITree(argv+1, argc-1, &end); printf("入力データ "); printBITree(p,0,1); destroyBITree(p); return 0; }

  • (構造体)ループ条件のscanf文が処理されない!?

    ループのscanf文を入力していないのに勝手にループの中に入って処理をしています。なぜでしょうか? #include<stdio.h> #include<malloc.h> #include<process.h> typedef struct node{ struct node *left; char name[20]; int age; struct node *right; }NODE; NODE *memalloc(void); void main(void) { NODE *head, *p, *old; /*ダミーノード作成*/ p = memalloc(); head = p; p -> left = p; p -> right = p; old = head; p = memalloc(); printf("名前 年齢入力 >"); scanf("%s, %d", p -> name, &p -> age); old -> left = p; old -> right = p; p -> left = old; p -> right = old; while(p = memalloc(), old = p, printf("名前 年齢入力 >"), scanf("%s, %d", p -> name, &p -> age) != EOF){ printf("確認\n"); old -> right = p; p -> left = old; head -> left = p; p -> right = head; } p = head -> right; while(head -> left != p -> right){ printf("名前:%20s 年齢:%5d\n", p -> name, p -> age); p = p -> right; } } NODE *memalloc(void) { NODE *ptr; if((ptr = (NODE *)malloc(sizeof(NODE))) != NULL){ return ptr; } printf("\n動的メモリ割当に失敗しました。\n"); exit(1); return(0); }

  • メモリ動的確保について

    こんにちはです。 メモリの動的確保なのですが、 typedef struct DATA{ char name[256]; char pass[256]; int money; }BANK; void insert(BANK *p,int max); int main(){ int i; size_t st; BANK *person; person = (struct DATA *)malloc(sizeof(struct DATA)); //person = (struct DATA *)malloc(5); if(person == NULL){ printf("確保失敗\n"); exit(-1); } //memset(person,'\0',sizeof(struct DATA)); と、言う風に、記載ソースは途中ですがメモリをとりました。 mallocの後ろの部分ですが、sizeof(struct DATA)と5ではどうちがうのでしょう??2通りともコンパイルエラーはないです。 5は動的に最大5までとるって事はわかるのですが、struct DATAの方はいくつとるのです??いくつもで入力次第です? そして、動的したのにたいしてmemsetしたら実行エラー(コンパイルは通りました)おきました。動的にたいしてmemはダメなのでしょうか? アドバイスいただけたらありがたいです。宜しくお願いいたします。

  • 二分木のデータ入力について

    C言語についての質問です。 キューと再起関数を使って2分木にデータを入れようとしたところ、以下のようなエラーが発生いたしました。 ddd.c: 関数 ‘dequeue’ 内: ddd.c:80:9: 警告: 戻りでポインタからキャスト無しに整数を作成しています [-Wint-conversion] return x; ^ ddd.c: 関数 ‘growTree’ 内: ddd.c:100:14: エラー: assignment to expression with array type x->sentence = dequeue(); なんとか解消しようとするのですが、どうしてもエラーが増えるばかりで、うまくいきませんでした。 どの部分をどのように直せばいいのか大変お手数ですが、教えていただけると助かります。 よろしくお願いいたします。 以下が実行したプログラムになっております。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define QUEUE_SIZE 100 /*キューの大きさ*/ /*配列でキューを表現する*/ int front, rear; char queue[3][50] = {"0b", "Ab", "Bb"}; char dequeue();/*キューからデータを取り出す*/ int next(int val);/*キューを配列で表現するとき、現在の次の配列のindexを返す*/ struct node{ char sentence[50];//値 struct node *left; //次のセルへのポインタ(左の子) struct node *right; //次のセルへのポインタ(右の子) }; int Gcount=0; void error(char *s);/*エラーを出力する*/ struct node* make_node();/*nodeをつくって返す*/ //void set_value_of_node(struct node* node,int a);/*nodeに値をセットする*/ struct node* growTree(int i, int k);/*深さiまで木を成長させ、そのルートを返す*/ void displayTree(struct node *node);/*node以下の部分木を表示する*/ int main(void){ struct node *root; int total=2 ; front = 0; rear = front + total + 1; root=growTree(total, 0); printf("\n\n\n前 順 表 示\n"); displayTree(root); return 0; } struct node* make_node(){/*nodeをつくって返す*/ struct node *p; if((p=(struct node*)malloc(sizeof(struct node ))) == NULL) error("メモリが足りません\n"); p->left =NULL; p->right =NULL; return(p); } //id set_value_of_node(struct node* node, int a)/*nodeに値をセットする*/ // //f(node == NULL)error("nodeが空です\n"); //ode->value=a; //rintf("%d ", node->value); // // void error(char *s){/*エラーを出力する*/ fprintf(stderr, s); exit(1); } /*キューからデータを取り出す*/ char dequeue(){ char *x; if(front == rear){ error("\nqueue is empty!!\n"); } x = queue[front]; front = next(front); return x; } /*キューを配列で表現するとき、現在の次の配列のindexを返す*/ int next(int val){ int next; next=(val+1)%QUEUE_SIZE; return(next); } struct node* growTree(int i, int k){/*深さiまで木を成長させ、そのルートを返す*/ /*課題1はここを書く*/ if(i == k) return NULL; k++; struct node *x; x = make_node(); x->sentence = dequeue(); x->left = growTree(i, k); x->right = growTree(i, k); return x; } void displayTree(struct node *node){/*node以下の部分木を表示する*/ /*課題2はここを書く*/ if(node == NULL) return; printf("%s\n", node->sentence); displayTree(node->left); displayTree(node->right); }

  • 二分探索木のプログラム

    2分探索木のプログラムを作っているのですが、実行するとセグメテーション違反がでます。何が間違っているんでしょうか? #include<stdlib.h> struct node{ struct node *left,*right; int datum; }; struct bintree{ struct node *root; }; /*空木を作成*/ void InitTree(struct bintree *p) { p->root=NULL; } /*木全体を削除*/ void ClearTree(struct bintree *p) { struct bintree *q,*r; if(p->root!=NULL){ q->root=p->root->left; ClearTree(q); r->root=p->root->right; ClearTree(r); free(p->root); } } /*第二引数で指定された値が木の節点のラベルに存在すれば、その節点へのポインタを返す。なければ、NULLを返す。*/ struct node * SearchNode(struct bintree *p,int x) { struct bintree *q,*r; struct node *a=p->root; int cond=x-(a->datum); if(a==NULL) return NULL; else if(cond==0) return a; else if(cond<0){ q->root=p->root->left; SearchNode(q,x); } else{ r->root=p->root->right; SearchNode(r,x); } } /*第二引数で指定された値が木の節点のラベルに存在すれば、NULLを返す。なければ、追加して、新たに作成された節点へのポインタを返す。*/ struct node * InsertNode(struct bintree *p,int x) { struct bintree *q,*r; struct node *a=p->root; int cond=x-(a->datum); if(a==NULL){ a=(struct node *)malloc(sizeof(struct node)); a->datum=x; a->left=a->right=NULL; return a; } else if(cond==0) return NULL; else if(cond<0){ q->root=p->root->left; a->left=InsertNode(q,x); } else{ r->root=p->root->right; a->right=InsertNode(r,x); } } int main() { struct bintree *p; struct node *a; InitTree(p); a=InsertNode(p,5); InsertNode(p,3); InsertNode(p,0); InsertNode(p,10); SearchNode(p,5); ClearTree(p); return 0; }

  • 解析木

    ノードの中身を表示しながらトラバースする関数 void preorder(NodePointer node); void inorder(NodePointer node); void postorder(NodePointer node); を再帰を使って書きなさい。 という問題がとけません。どなたかアドバイスをください。 ちなみに、この関数以外は下のように作りました。 #include <stdio.h> #include <stdlib.h> struct node { struct node *right; char key; struct node *left; }; typedef struct node * NodePointer; void treeinitialize(void); NodePointer makenode(char c); void preorder(NodePointer node); void inorder(NodePointer node); void postorder(NodePointer node); NodePointer head, tail; int main(){ treeinitialize(); //テスト用の木を作成 head->right=makenode('+'); head->right->left=makenode('1'); head->right->right=makenode('*'); head->right->right->left=makenode('2'); head->right->right->right=makenode('3'); //トラバース printf("preorder: "); preorder(head->right); printf("\n"); printf("inorder: "); inorder(head->right); printf("\n"); printf("postorder: "); postorder(head->right); printf("\n"); return 0; } void treeinitialize(void){ head=makenode(-1); tail=makenode(-1); head->right=tail; head->left=tail; } //ノードを作成し、そのノードへのポインタを返す。 NodePointer makenode(char c){ NodePointer x; x=malloc(sizeof(struct node)); x->key=c; x->right=tail; x->left=tail; return x; } void preorder(NodePointer node){ } void inorder(NodePointer node){ } void postorder(NodePointer node){ }

  • C言語 リスト

    (1) /* list.c */ #include <stdio.h> #include <stdlib.h> struct node { int num; struct node *next; }; main() { struct node *head, *p; int x; head = NULL; while(scanf("%d",&x) != EOF) { p = (struct node *)malloc(sizeof(struct node)); p->num = x; p->next = head; head = p; } // リストの要素のnumの値を先頭から順に表示する p=head; while(p!=NULL) { printf("%d\n" ,p->num); p = p->next; } } (2) struct node *q; q = head; while(q->next != NULL) q = q->next; (1)を(2)を使い新しいノードをリストの最後に追加するようにしたいのですが どう書いたら良いのか教えていただきたいです

専門家に質問してみよう