回答編集履歴
8
malloc 記事へのリンク追加
test
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
また、きちんとするなら、 realloc が返すアドレスを直接 data に入れてはいけません。
|
9
9
|
realloc は指定したサイズのメモリが確保出来たら元の領域を解放して新しい領域を返しますが、確保出来なかった場合は元の領域は解放せず NULL を返します。(ちなみに**指定したサイズ分増やすわけではありません**。また、サイズが同じ/縮小の場合は元の領域を流用して元のアドレスを返す場合もあります。)
|
10
10
|
返した値を data に入れてしまうと、 NULL だった場合に元の領域を解放することが出来ません。
|
11
|
+
→ [【C言語】realloc関数|正しい使い方と注意点 メモリ断片化など](https://marycore.jp/prog/c-lang/realloc/)
|
11
12
|
さらに、確保したメモリのサイズは入力したデータの数と一致しませんので、表示に size 分ループすると、 20 個分のメモリを確保しても 12 件しか入力しなかった場合、 13 件目以降は無駄にデタラメなデータが表示されてしまいます。
|
12
13
|
|
13
14
|
```c
|
7
修正
test
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
ご質問のコードでは、 size 変数の使い方が逆です。
|
7
7
|
malloc/realloc した結果から size を求めるのではなく、 size の値から malloc/realloc する大きさを求めるべきです。
|
8
8
|
また、きちんとするなら、 realloc が返すアドレスを直接 data に入れてはいけません。
|
9
|
-
realloc はメモリが確保出来たら元の領域を解放して新しい領域を返しますが、確保出来なかった場合は元の領域は解放せず NULL を返します。(ちなみに**指定したサイズ分増やすわけではありません**。)
|
9
|
+
realloc は指定したサイズのメモリが確保出来たら元の領域を解放して新しい領域を返しますが、確保出来なかった場合は元の領域は解放せず NULL を返します。(ちなみに**指定したサイズ分増やすわけではありません**。また、サイズが同じ/縮小の場合は元の領域を流用して元のアドレスを返す場合もあります。)
|
10
10
|
返した値を data に入れてしまうと、 NULL だった場合に元の領域を解放することが出来ません。
|
11
11
|
さらに、確保したメモリのサイズは入力したデータの数と一致しませんので、表示に size 分ループすると、 20 個分のメモリを確保しても 12 件しか入力しなかった場合、 13 件目以降は無駄にデタラメなデータが表示されてしまいます。
|
12
12
|
|
6
修正
test
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
ご質問のコードでは、 size 変数の使い方が逆です。
|
7
7
|
malloc/realloc した結果から size を求めるのではなく、 size の値から malloc/realloc する大きさを求めるべきです。
|
8
8
|
また、きちんとするなら、 realloc が返すアドレスを直接 data に入れてはいけません。
|
9
|
-
realloc はメモリが確保出来たら元の領域を解放して新しい領域を返しますが、確保出来なかった場合は元の領域は解放せず NULL を返します。
|
9
|
+
realloc はメモリが確保出来たら元の領域を解放して新しい領域を返しますが、確保出来なかった場合は元の領域は解放せず NULL を返します。(ちなみに**指定したサイズ分増やすわけではありません**。)
|
10
10
|
返した値を data に入れてしまうと、 NULL だった場合に元の領域を解放することが出来ません。
|
11
11
|
さらに、確保したメモリのサイズは入力したデータの数と一致しませんので、表示に size 分ループすると、 20 個分のメモリを確保しても 12 件しか入力しなかった場合、 13 件目以降は無駄にデタラメなデータが表示されてしまいます。
|
12
12
|
|
5
修正
test
CHANGED
@@ -8,25 +8,25 @@
|
|
8
8
|
また、きちんとするなら、 realloc が返すアドレスを直接 data に入れてはいけません。
|
9
9
|
realloc はメモリが確保出来たら元の領域を解放して新しい領域を返しますが、確保出来なかった場合は元の領域は解放せず NULL を返します。
|
10
10
|
返した値を data に入れてしまうと、 NULL だった場合に元の領域を解放することが出来ません。
|
11
|
+
さらに、確保したメモリのサイズは入力したデータの数と一致しませんので、表示に size 分ループすると、 20 個分のメモリを確保しても 12 件しか入力しなかった場合、 13 件目以降は無駄にデタラメなデータが表示されてしまいます。
|
11
12
|
|
12
13
|
```c
|
13
14
|
int main(void) {
|
14
15
|
int size = 10; //初期サイズ
|
16
|
+
int last = 0;
|
15
17
|
|
16
18
|
people *data = malloc(sizeof(people) * size);
|
17
19
|
if(data == NULL) exit(0);
|
18
20
|
|
19
21
|
printf("情報を入力して下さい。(入力終了なら年齢に-1)\n");
|
20
22
|
|
21
|
-
|
23
|
+
while(1) {
|
22
|
-
|
23
|
-
inputpeople(&data[
|
24
|
+
inputpeople(&data[last]);
|
24
|
-
|
25
|
-
if(data[
|
25
|
+
if(data[last].age == -1) {
|
26
26
|
break;
|
27
27
|
}
|
28
28
|
|
29
|
-
if(
|
29
|
+
if(++last == size) {
|
30
30
|
size += 10;
|
31
31
|
people *p = realloc(data, sizeof(people) * size);
|
32
32
|
if(p == NULL) { //realloc エラー
|
@@ -37,7 +37,7 @@
|
|
37
37
|
}
|
38
38
|
}
|
39
39
|
|
40
|
-
for(int i = 0; i < s
|
40
|
+
for(int i = 0; i < last; i++) {
|
41
41
|
showpeople(data[i]);
|
42
42
|
}
|
43
43
|
|
4
追加
test
CHANGED
@@ -1,3 +1,48 @@
|
|
1
1
|
sizeof(data) は people *data なのですから ポインタのサイズ(4 とか 8 でしょうか)が返ります。
|
2
2
|
sizeof(data[0]) は people のサイズ(72 とか 80 とか) ですので、整数同士の割り算で切り捨てられて 0 となります。
|
3
3
|
おかしいと思われたなら、まず size(data) や size(data[0]) を printf して確認するのが良いと思います。
|
4
|
+
|
5
|
+
---
|
6
|
+
ご質問のコードでは、 size 変数の使い方が逆です。
|
7
|
+
malloc/realloc した結果から size を求めるのではなく、 size の値から malloc/realloc する大きさを求めるべきです。
|
8
|
+
また、きちんとするなら、 realloc が返すアドレスを直接 data に入れてはいけません。
|
9
|
+
realloc はメモリが確保出来たら元の領域を解放して新しい領域を返しますが、確保出来なかった場合は元の領域は解放せず NULL を返します。
|
10
|
+
返した値を data に入れてしまうと、 NULL だった場合に元の領域を解放することが出来ません。
|
11
|
+
|
12
|
+
```c
|
13
|
+
int main(void) {
|
14
|
+
int size = 10; //初期サイズ
|
15
|
+
|
16
|
+
people *data = malloc(sizeof(people) * size);
|
17
|
+
if(data == NULL) exit(0);
|
18
|
+
|
19
|
+
printf("情報を入力して下さい。(入力終了なら年齢に-1)\n");
|
20
|
+
|
21
|
+
for(int i = 0; i < size; i++) {
|
22
|
+
|
23
|
+
inputpeople(&data[i]);
|
24
|
+
|
25
|
+
if(data[i].age == -1) {
|
26
|
+
break;
|
27
|
+
}
|
28
|
+
|
29
|
+
if(i == size - 1) {
|
30
|
+
size += 10;
|
31
|
+
people *p = realloc(data, sizeof(people) * size);
|
32
|
+
if(p == NULL) { //realloc エラー
|
33
|
+
free(data);
|
34
|
+
exit(0);
|
35
|
+
}
|
36
|
+
data = p;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
for(int i = 0; i < size; i++) {
|
41
|
+
showpeople(data[i]);
|
42
|
+
}
|
43
|
+
|
44
|
+
free(data);
|
45
|
+
|
46
|
+
return 0;
|
47
|
+
}
|
48
|
+
```
|
3
追加
test
CHANGED
@@ -1,2 +1,3 @@
|
|
1
1
|
sizeof(data) は people *data なのですから ポインタのサイズ(4 とか 8 でしょうか)が返ります。
|
2
2
|
sizeof(data[0]) は people のサイズ(72 とか 80 とか) ですので、整数同士の割り算で切り捨てられて 0 となります。
|
3
|
+
おかしいと思われたなら、まず size(data) や size(data[0]) を printf して確認するのが良いと思います。
|
2
追加
test
CHANGED
@@ -1 +1,2 @@
|
|
1
1
|
sizeof(data) は people *data なのですから ポインタのサイズ(4 とか 8 でしょうか)が返ります。
|
2
|
+
sizeof(data[0]) は people のサイズ(72 とか 80 とか) ですので、整数同士の割り算で切り捨てられて 0 となります。
|
1
修正
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
sizeof(data) は people *data なのですから ポインタのサイズが返ります。
|
1
|
+
sizeof(data) は people *data なのですから ポインタのサイズ(4 とか 8 でしょうか)が返ります。
|