ポインタのエラー?

このQ&Aのポイント
  • 配列とポインタを使って多数桁の加算をするプログラムでエラーが発生します。
  • 初心者なのでコードの書式がばらばらで読みにくいです。
  • メモリ領域の解放も行っています。
回答を見る
  • ベストアンサー

ポインタのエラー?

配列とポインタを使って多数桁の加算をするプログラムを作ったのですが、演算結果を表示した後にエラーが出てしまいます。初心者なので書式もばらばらで読みにくいと思いますが、お願いします。 #include <stdio.h> #include <stdlib.h> #define N 10 void main() { int *a,*b,*result,carry,i; a=(int *)calloc(N+1,sizeof(int)); b=(int *)calloc(N+1,sizeof(int)); result=(int *)calloc(N+1,sizeof(int)); /*配列aへの読み込み*/ for(i=1;i<N+1;i++) scanf("%d",&*(a+i)); *a=0; printf("入力された数値:"); for(i=1;i<N+1;i++) printf("%d",*(a+i)); printf("\n"); /*配列bへの読み込み*/ for(i=1;i<N+1;i++) scanf("%d",&*(b+i)); *b=0; printf("入力された数値:"); for(i=1;i<N+1;i++) printf("%d",*(b+i)); printf("\n"); /*配列resultの初期化*/ for(i=0;i<N+1;i++) *(result+i)=0; carry=0; /*result=a+bの演算*/ for(i=(N+1);i>=0;i--){ *(result+i)=*(a+i)+*(b+i)+carry; if(*(result+i)>=10){ *(result+i)-=10; carry=1; } else carry=0; } /*演算結果の表示*/ printf("和:"); for(i=0;i<N+1;i++) printf("%d",*(result+i)); printf("\n"); /*メモリ領域の解放*/ free(a); free(b); free(result); }

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

  • ベストアンサー
回答No.1

a=(int *)calloc(N+1,sizeof(int)); ... であることから、確保されたのは *(a+0) ... *(a+N) ところが for(i=(N+1);i>=0;i--){ *(result+i)=*(a+i)+*(b+i)+carry; ここで *(a+N+1) にアクセスします。 確保した領域を越えていませんか?

StudentYuta
質問者

補足

回答ありがとうございます。 ご指摘のとおりでした。 for(i=N;i>=0;i--) と変更したところエラーも出ず、正確に演算できました。 これから関数化してみたいと思います。

関連するQ&A

  • 二次元配列とポインタについてよくわかりません

    二次元配列の要素を代入しようと思って double *pa; for(i = 0; i < 4; i++){ for(j = 0; j < 4; j++){ printf("A[%d,%d]=", i + 1, j + 1 ); scanf("%lf", pa + i + j); printf("A[%d,%d]=%g\n", i + 1, j + 1, *(*(pa + i) + j) );}} とやっているのですがどうやらscanfで上手くいかず最後のprintfが表示されません あと double (*pb)[4]; printf("4 x 4 行列 Bの要素を入力してください>\n"); for(i = 0; i < 4; i++){ for(j = 0; j < 4; j++){ printf("B[%d,%d]=", i + 1, j + 1 ); scanf("%lf", &pb[i][j]);}} もうまくいきません (二通りの方法でしなければ成らないので) どうしたらいいでしょうか?

  • ポインターを使った並べ替え

    ポインタを用いてソートを行うプログラムを作成しています しかし、関数部分が悪いのか、上手く作動されません よろしければ、アドバイスをいただけると嬉しいです #include <stdio.h> #define MAX 10 #define RandMax 1000 void select_sort(int *a, int n){ int *i, *min, *last, t; last=a+n; for(i=a; i<last; i++){ min=a; for(i=a+1; i<last; i++) if(*i<*min) min=i; t=*min; *min=*i; *i=t; } } main(){ int *a, i; a=(int*)calloc(MAX,sizeof(int)); for(i=0; i<MAX; i++) a[i]=rand()%RandMax; select_sort(a, MAX); printf("data size=%d \n", MAX); for(i=0; i<MAX; i++){ printf("%5d", a[i]); if(i%10==9) printf("\n"); } } 以上が私の作成したプログラムです よろしくお願いします

  • 沢山の変数を扱う時、うまく出来ません・・。

    変数が沢山ある時、エラーが起こったかどうかは どうやって判断したらいいんでしょうか。 今50個位変数名があるとします。 今は端おって5つにします。 int a,b,d; char c,e a = (int *) calloc(500,sizeof(int)); b = (int *) calloc(200,sizeof(int)); c = (char *)calloc(700,sizeof(char)); d = (int *) calloc(400,sizeof(int)); e = (char *)calloc(100,sizeof(char)); if(a==NULL || b==NULL || c==NULL || d==NULL || e==NULL)   printf("エラー発生\n"); こうやって50個もif文の中にいれたら大変ですよね。 変数名も長いですし。うまく1つでもエラーが起きたら全体がエラーになるように出来ませんかね? 自分としてはこういう風に考えたんですけど int sum=1; a = (int *) calloc(500,sizeof(int)); sum*=a; b = (int *) calloc(200,sizeof(int)); sum*=b; c = (char *)calloc(700,sizeof(char)); sum*=c; d = (int *) calloc(400,sizeof(int)); sum*=d; e = (char *)calloc(100,sizeof(char)); sum*=e; if(sum==0)   printf("エラー発生\n"); コレくらいしかないですかね?

  • C#でポインタのポインタを作りたい

    昔VC++で作ったDLLをC#で使おうと思ったのですが、なんと、その引数がint**型です。 やっていることは、intの配列がありまして、その配列の特定の要素のアドレスを納めた配列を使っています。 具体的には(型や関数記述は大まかに書きます) --------------------------------- int **array; int *item; array = calloc(10, sizeof(int)); item = calloc(1000, sizeof(int)); for (i = 0; i < 10; i++) { array[i] = item + i+100; } --------------------------------- とした、arrayを引数にしています。 これをC#から使おうとして、C#ではint**をどうするんだろうと思った次第です。 わからないのは、C#でどうやってアドレスを配列に入れるかです。 array[i] = &item[width*i] とすると、コンパイル段階で怒られてしまいますし... 知恵をお貸しください。

  • このプログラムの間違いを指摘していただけませんか?

    まだ、初めて一ヶ月も経たない者です。それでも、勉強しつつ、組んでみたのですが、うまくいきません。数字の足し算をして、結果を表示させたいのですが、四回足しても四回目の数字が、足されずに結果がでてしまいます。1と2と3と4と入力すると、6と出てきます。一体どのようにしたらよいのでしょうか?教えて頂けませんか?(下に書いてあります。) #include <stdio.h> int sub(int x, int y, int z){ return x + y + z; } int main() { int i; int a[i]; for (i=1; i<=1; ++i){ printf("数字は?\n"); scanf ("%d\n", &a[i]); scanf ("%d\n", &a[i+1]); scanf ("%d\n", &a[i+2]); scanf ("%d\n", &a[i+3]); int result,x,y,z; result = sub(a[i],a[i+1],a[i+2]); printf("結果は%d\n",result); } return 0; }

  • ポインタと配列 助けてください

    #include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 0}; int i, *ptr; ptr = ######; while (*ptr != 0){ ######; ######; }      for (i = 0; i < 5; i++) printf("a[%d]=%2d &a[%d]=%p\n", i, #####,i, #####); putchar('\n'); ptr = ######; for (i = 0; i < 5; i++){ printf("ptr値 =%d ptrアドレス =%p \n", ####, ####); ####; } printf("\n"); return (0); } 一次元配列a[]の一番目の要素以外を0にするプログラム(ただし、最後の要素は0)を作成したいのですが、#の部分に何をあてはめたらいいかわかりません。 助けてください。

  • ポインタ

    C言語のポインタの勉強をしています。//エラー と書いている行でエラーがでます。*(a++),*(b++),*(c++)をそれぞれ*(a+i),*(b+i),*(c+i)とすればエラーがなくなるのですが、違いがわかりません。 先頭アドレスをセットしてないからエラーが出たのかと思いましたが、それが原因なら*(a+i),*(b+i),*(c+i)でエラーがなくなるのはどうしてでしょうか? 違いを教えて下さい。よろしくお願いします。 #include<stdio.h> int main(void) { void p_add(int *a, int *b, int *n); int i; int a[10] = {3,7,1,2,8,9,0,4,6,5}; int b[10] = {7,3,9,8,2,1,10,6,4,5}; int c[10]; memset(c,0x00,sizeof(c)); p_add(a, b, c); for(i = 0; i < 10; i++){ printf("a[%d]=%d b[%d]=%d c[%d]=%d\n", i, *(a++), i, *(b++), i, *(c+ +));                                               // エラー } return 0; } void p_add(int *a, int *b, int *n){ int i; for(i = 0; i < 10; i++){ *(n++) = *(a++) + *(b++); } }

  • callocで二次元配列を作成するには?

    今、動的オブジェクトの勉強をしております。 動的の一次元配列の作り方として #include <stdio.h> #include <stdlib.h> int main(void) {    int *a;    int x;    printf("配列の大きさX入力>");    scanf("%d",&x);    a=calloc(x,sizeof(int));    return (0); } これでいいと思うんですが動的な2次元配列を 作りたいときはどのようにすればよろしいのでしょうか? (↓作りたい二次元配列の例(1)↓) int main(void) {    int *a;    int x , y;    printf("配列の大きさX入力>");    scanf("%d",&x);         //5と入力    printf("配列の大きさY入力>");    scanf("%d",&y);         //10と入力    上のように入力するとa[5][10]という配列が完成する } よろしくお願いします

  • 二次元配列とポインタについてよくわかりません2

    先ほどもしつもんして自分なりに改良をくわえたのですが 上手くいきません。 int main( void ) {  int i, j;  /*4 x 4 行列 A*/  double a[4][4];  double *pa;  /*4 x 4 行列 B*/  double b[4];  double (*pb)[4];  /*4 x 4 行列 C*/  double c[4];  double (*pc)[4];  pa = a;  pb = b;  pc = c;  printf("4 x 4 行列 Aの要素を入力してください>\n");  for(i = 0; i < 4; i++){   for(j = 0; j < 4; j++){    printf("A[%d,%d]=", i + 1, j + 1 );    scanf("%lf", (*(pa + i) + j)); }} printf("4 x 4 行列 Bの要素を入力してください>\n"); for(i = 0; i < 4; i++){  for(j = 0; j < 4; j++){   printf("B[%d,%d]=", i + 1, j + 1 );   scanf("%lf", &pb[i][j]); }} としたところ(途中までを表記してます)  pa = a;  pb = b;  pc = c; のところでコンパイル時に 警告で問題のあるポインタの変換とでます なぜおかしいのかまったくわからないので よければ教えてください

  • 構造体配列のメモリ確保

    以下のようなプログラムを作りました。 make_mem関数のなかで構造体のメモリを確保し、 データを代入しています。 しかし、mainに返ってくると値が代入されていません。 よく調べてみると、mainで宣言してあるdataのアドレスが 変更されていません。 どのようにすれば、meake_memoのなかでメモリ確保し、 データを代入できるのでしょうか? 教えてください。 実際の使用しているプログラムはmake_memoのなかで DBを開き、そのデータを配列に代入しているので、 main関数の中では配列の大きさがわかりません。 #include <stdio.h> typedef struct { int a; int b; }DATA; int make_mem(DATA *data){ int i; data=(DATA *)calloc(10,sizeof(DATA)); printf("calloc %p\n",data); for (i=0;i<10;i++){ data[i].a = i; printf("data[%d].a = %d\n",i,data[i].a); } return 0; } int main(int argc,char *argv[]){ DATA *data; int i; printf("before %p\n",data); make_mem(data); printf("after %p\n",data); for (i=0;i<10;i++){ printf("data[%d].a = %d\n",i,data[i].a); } return 0; }

専門家に質問してみよう