double 型の配列、要素数 n 個分のメモリを取得しようとして
C
1 x = (double *)malloc(n); // (X)
2 y = (double *)malloc(n); // (Y)
としたことが間違いなのは、既に他の方々が指摘した通りですが、質問者には状況が見えていないと思います。
このコードで質問者は次のようなメモリ配置を期待したはずです。
しかし malloc(n)
では、このようなメモリ配置になりません。
必要なメモリが確保されず、x と y の領域が重なってしまいます。
x[31]=10と入力しているにもかかわらず、
計算の結果y[19]=15となるとx[31]=15と表示される
これは、x と y の領域が重なった結果、x[31] と y[19] は(名前は違うのに)同じメモリになっている事を示しています。
この状況を再現できる条件は、n == 80 の場合だと推測しました(今時は64bit版コンパイラを使っていると思うので)。そこで、次のコードを試してみてください。
C
1#include<stdio.h>
2#include<stdlib.h>
3
4int main(){
5 int n = 80; // この値で状況を再現できるだろう
6 double *x, *y, *z;
7
8 // double に必要なバイト数を表示する
9 printf("sizeof(double) = %ld\n", sizeof(double));
10
11 // メモリを取得する(ここに誤りがある)
12 x = (double *)malloc(n); // (X)
13 y = (double *)malloc(n); // (Y)
14 z = (double *)malloc(n * sizeof(double)); // (Z) 念のため
15
16 // 取得したメモリのアドレスを表示する
17 printf(" x = %p\n y = %p\n\n", x, y);
18
19 // x[] に順に値を格納する
20 for(int i = 0; i < n; i++)
21 x[i] = (double)i;
22
23 // x[] を表示
24 printf("x[] : ");
25 for(int i = 0; i < n; i++) {
26 printf("%.2lf, ", x[i]);
27 }
28 printf("\n\n");
29
30 // y[] を表示
31 printf("y[] : ");
32 for(int i = 0; i < n; i++) {
33 printf("%.2lf, ", y[i]);
34 }
35 printf("\n\n");
36
37 // 再確認
38 printf(" x = %p\n y = %p\n", x, y); // x, y は変化しない
39 printf("x[31] = %.2lf (%p)\n", x[31], &x[31]); // x[31] と
40 printf("y[19] = %.2lf (%p)\n", y[19], &y[19]); // y[19] は同一メモリ
41
42 // free() できるか?
43 printf("free(x)\n"); free(x); // x を free() できたとしても
44 printf("free(y)\n"); free(y); // y は free() できないだろう
45 return 0;
46}
私が手元の GCCでコンパイルし、実行させた結果です。
$ ./a.out
sizeof(double) = 8
x = 0x55861f7b92a0
y = 0x55861f7b9300
x[] : 0.00, 1.00, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00, 11.00, 12.00, 13.00, 14.00, 15.00, 16.00, 17.00, 18.00, 19.00, 20.00, 21.00, 22.00, 23.00, 24.00, 25.00, 26.00, 27.00, 28.00, 29.00, 30.00, 31.00, 32.00, 33.00, 34.00, 35.00, 36.00, 37.00, 38.00, 39.00, 40.00, 41.00, 42.00, 43.00, 44.00, 45.00, 46.00, 47.00, 48.00, 49.00, 50.00, 51.00, 52.00, 53.00, 54.00, 55.00, 56.00, 57.00, 58.00, 59.00, 60.00, 61.00, 62.00, 63.00, 64.00, 65.00, 66.00, 67.00, 68.00, 69.00, 70.00, 71.00, 72.00, 73.00, 74.00, 75.00, 76.00, 77.00, 78.00, 79.00,
y[] : 12.00, 13.00, 14.00, 15.00, 16.00, 17.00, 18.00, 19.00, 20.00, 21.00, 22.00, 23.00, 24.00, 25.00, 26.00, 27.00, 28.00, 29.00, 30.00, 31.00, 32.00, 33.00, 34.00, 35.00, 36.00, 37.00, 38.00, 39.00, 40.00, 41.00, 42.00, 43.00, 44.00, 45.00, 46.00, 47.00, 48.00, 49.00, 50.00, 51.00, 52.00, 53.00, 54.00, 55.00, 56.00, 57.00, 58.00, 59.00, 60.00, 61.00, 62.00, 63.00, 64.00, 65.00, 66.00, 67.00, 68.00, 69.00, 70.00, 71.00, 72.00, 73.00, 74.00, 75.00, 76.00, 77.00, 78.00, 79.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,
x = 0x55861f7b92a0
y = 0x55861f7b9300
x[31] = 31.00 (0x55861f7b9398)
y[19] = 31.00 (0x55861f7b9398)
free(x)
free(y)
double free or corruption (out)
中止 (コアダンプ)
x[31] と y[19] は、メモリアドレスが同じ、即ち同じメモリであることを示しています。ですから同じ値なのです。
変数はメモリ上に割当てられます。
- メモリは1バイト(8bit)を単位としてアドレスが割り振られている
- 変数の型によって変数に必要なメモリサイズは異なる
例えば、sizeof(double) の値は「8」です(表示されています)。
double型は64bitなので、メモリ上では8バイトが必要です。
もし n = 80 の場合、要素数80個分のメモリが必要になりますので、80 * 8 = 640 バイトのメモリが必要です。
- malloc() の引数は取得しようとするメモリのバイト数を指定する
従って malloc(640)
としなければならないのに、(X), (Y) とも malloc(n)
即ち malloc(80)
としています。どちらも80バイトしかメモリを取得できず、double の値10個分しか格納できません。
つまり、x[0] ~ x[9] と y[0] ~ y[9] の分しかメモリを取得できていません。
その結果、x, y で取得した領域は次の図のようになります。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。