質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

解決済

3回答

3715閲覧

mallocでのエラーの原因

ksyiwk

総合スコア24

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

0グッド

0クリップ

投稿2019/11/21 11:10

先日N次正方行列AとN次元ベクトルxの積y=Axを計算するプログラムについて質問したものです。計算結果は正しく出力されたのですが以下のエラー文も一緒に出てしまいました。mallocでのメモリの確保と開放で何かミスをしたと思われますがどうすればいいのかわかりません。どなたか教えて下さい。

*** Error in `./prog07.exe': free(): invalid pointer: 0x000000000087e014 ***

======= Backtrace: =========
/lib64/libc.so.6(+0x7c503)[0x7f2bf89dd503]
./prog07.exe[0x400a8b]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f2bf8982b35]
./prog07.exe[0x400649]
======= Memory map: ========
00400000-00401000 r-xp 00000000 00:2e 1671678911 /jugyou/elect/16D5104006B/
practice05/exp08/prog07.exe
00600000-00601000 r--p 00000000 00:2e 1671678911 /jugyou/elect/16D5104006B/
practice05/exp08/prog07.exe
00601000-00602000 rw-p 00001000 00:2e 1671678911 /jugyou/elect/16D5104006B/
practice05/exp08/prog07.exe
0087e000-0089f000 rw-p 00000000 00:00 0 [heap]
7f2bf4000000-7f2bf4021000 rw-p 00000000 00:00 0
7f2bf4021000-7f2bf8000000 ---p 00000000 00:00 0
7f2bf874b000-7f2bf8760000 r-xp 00000000 fd:01 207080590 /usr/lib64/
libgcc_s-4.8.5-20150702.so.1
7f2bf8760000-7f2bf895f000 ---p 00015000 fd:01 207080590 /usr/lib64/
libgcc_s-4.8.5-20150702.so.1
7f2bf895f000-7f2bf8960000 r--p 00014000 fd:01 207080590 /usr/lib64/
libgcc_s-4.8.5-20150702.so.1
7f2bf8960000-7f2bf8961000 rw-p 00015000 fd:01 207080590 /usr/lib64/
libgcc_s-4.8.5-20150702.so.1
7f2bf8961000-7f2bf8b17000 r-xp 00000000 fd:01 205769967 /usr/lib64/libc-2.17.so
7f2bf8b17000-7f2bf8d17000 ---p 001b6000 fd:01 205769967 /usr/lib64/libc-2.17.so
7f2bf8d17000-7f2bf8d1b000 r--p 001b6000 fd:01 205769967 /usr/lib64/libc-2.17.so
7f2bf8d1b000-7f2bf8d1d000 rw-p 001ba000 fd:01 205769967 /usr/lib64/libc-2.17.so
7f2bf8d1d000-7f2bf8d22000 rw-p 00000000 00:00 0
7f2bf8d22000-7f2bf8d42000 r-xp 00000000 fd:01 207080593 /usr/lib64/ld-2.17.so
7f2bf8f24000-7f2bf8f27000 rw-p 00000000 00:00 0
7f2bf8f3d000-7f2bf8f41000 rw-p 00000000 00:00 0
7f2bf8f41000-7f2bf8f42000 r--p 0001f000 fd:01 207080593 /usr/lib64/ld-2.17.so
7f2bf8f42000-7f2bf8f43000 rw-p 00020000 fd:01 207080593 /usr/lib64/ld-2.17.so
7f2bf8f43000-7f2bf8f44000 rw-p 00000000 00:00 0
7ffc26e89000-7ffc26eab000 rw-p 00000000 00:00 0 [stack]
7ffc26fda000-7ffc26fdc000 r--p 00000000 00:00 0 [vvar]
7ffc26fdc000-7ffc26fde000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

ソースコードは以下の通りです。

#include<stdio.h> #include<stdlib.h> void PrintVector(int *x, int n){ int i; for(i=0;i<n;i++){ printf("%6d\n",*(x+i)); } } void PrintMatrix(int *a, int n){ int i,j; int *ai; ai=a; for( i = 0 ; i < n ; i++){ for( j = 0 ; j < n ; j++){ printf("%6d", *(ai+j)); } ai+=n; printf("\n"); } printf("\n"); } int main(){ int i, j,n; int *ai;/* 各行の先頭へのポインタを表すポインタを用意する */ int *a, *x, *y;/* 計算結果を代入するための行列を用意 */ printf("N:"); scanf("%d",&n); ai= (int *) malloc(n*sizeof(int)); x= (int *) malloc(n*sizeof(int)); y= (int *) malloc(n*sizeof(int)); if(x==NULL ||y==NULL || ai==NULL){ printf("Can’t allocate memory. \n"); exit(1); } a=ai; for(i=0;i<n;i++){ for(j=0;j<n;j++){ printf("A[%d][%d]=",i,j); scanf("%d",ai+j); } ai+=n; } for(i=0;i<n;i++){ printf("X[%d]=",i); scanf("%d",x+i); } printf("A = \n"); PrintMatrix(a,n); printf("x = \n"); PrintVector(x,n); ai=a; for(i=0;i<n;i++){ for(j=0;j<n;j++){ *(y+i)+=*(ai+j)**(x+j); } ai+=n; } printf("y = \n"); /* ベクトル y(=Ax) の表示 */ for(i=0;i<n;i++){ printf("%6d\n",*(y+i)); } free(ai); free(x); free(y); return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ざっと見ただけですが、、、

ai= (int ) malloc(nsizeof(int));

ここで、整数(int)のn個分の配列が確保されています。
その後、

C

1 for(i=0;i<n;i++){ 2 for(j=0;j<n;j++){ 3 printf("A[%d][%d]=",i,j); 4 scanf("%d",ai+j); 5 6 } 7 ai+=n;

では、 n x n 個の配列(領域)アクセスが行われているように見えます。
これは、malloc()で確保された以上の領域に書き込まれていると思います。

[追記]
他の方の回答を見ると、free()で問題発生ですね。(見落とし)
上記の範囲外アクセスで、次の malloc()の確保領域を壊した?

投稿2019/11/21 11:24

編集2019/11/21 11:27
pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dameo

2019/11/21 12:41

きちんと説明しておくと、scanf("%d",ai+j);で、N個しか確保されていない領域にNxN個分書き込んでいますね。バッファーオーバーフローによるメモリ破壊というやつです。 そのため、まずは ai= (int *) malloc(n*sizeof(int)); を ai= (int *) malloc(n*n*sizeof(int)); に修正する必要があります。 また、free(ai);ではaiがyを計算したときのアドレスが入っているので、a+n*n相当を指しています。 確保したアドレスがaなので、アドレスが違っており、エラーで怒られたというわけです。 他の回答者さんがご指摘されているとおり、free(a);などの修正が必要です。
guest

0

ベストアンサー

aiは62行目で加算しているので、mallocで確保した先頭アドレスを指していません。
ここでは最初にaiを退避しておいたaをfreeするべきかと。

投稿2019/11/21 11:23

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

free(ai); で開放するのは何処?

投稿2019/11/21 11:18

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問