teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

誤字修正

2020/04/27 00:53

投稿

aardvark
aardvark

スコア17

title CHANGED
File without changes
body CHANGED
@@ -236,6 +236,6 @@
236
236
  ==152== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
237
237
  ```
238
238
 
239
- このように、smatrix_readやsmatrix_transposesmatrix_freeで新しい行列を作成し、そこに順次リストの要素を挿入していく際に確保したリスト要素のメモリはsmatrix_freeやその中のslist_freeで全て解放しているはずなのですが、どうやら全部解放しきれていないようです。(問題がありそうな個所はコードの中でその旨をコメントしておきました)
239
+ このように、smatrix_readやsmatrix_transposesで新しい行列を作成し、そこに順次リストの要素を挿入していく際に確保したリスト要素のメモリはsmatrix_freeやその中のslist_freeで全て解放しているはずなのですが、どうやら全部解放しきれていないようです。(問題がありそうな個所はコードの中でその旨をコメントしておきました)
240
240
 
241
241
  slist_freeの記述がおかしいのでしょうか。

1

コードを編集し、valgrindを使ってデバッグした結果を追加しました

2020/04/27 00:53

投稿

aardvark
aardvark

スコア17

title CHANGED
File without changes
body CHANGED
@@ -8,29 +8,34 @@
8
8
  どなたか、ご教授いただければ幸いです。
9
9
  宜しくお願いいたします。
10
10
 
11
+ 編集:コードが長ったらしい上に、実際valgrindでどういう出力があったのかについては全く言及しておりませんでしたね。大変失礼いたしました。
11
12
  ```C
12
13
  #include <stdio.h>
13
14
  #include <string.h>
14
15
  #include <stdlib.h>
15
16
 
16
- #define NEW(p, n){p = malloc((n)*sizeof(p[0]));}
17
+ #define NEW(p, n){p = malloc((n)*sizeof(p[0]));} //動的メモリ確保の関数
17
18
 
19
+ //リストの要素の構造体
18
20
  typedef struct slobj_{
19
21
  struct slobj_* next;
20
22
  int j;
21
23
  double v;
22
24
  }* slobj;
23
25
 
26
+ //リストの構造体
24
27
  typedef struct{
25
28
  slobj head;
26
29
  slobj tail;
27
30
  }* slist;
28
31
 
32
+ //疎行列の構造体(リストの配列ということ)
29
33
  typedef struct{
30
34
  int n,m;
31
35
  slist* A;
32
- } smatrix;
36
+ } smatrix; 
33
37
 
38
+ //新しいリストを作成
34
39
  slist slist_new(void){
35
40
  slist L;
36
41
  NEW(L, 1);
@@ -39,6 +44,7 @@
39
44
  return L;
40
45
  }
41
46
 
47
+ //新しいリストの要素を作成
42
48
  slobj slobj_new(int x, double y){
43
49
  slobj p;
44
50
  NEW(p, 1);
@@ -48,11 +54,13 @@
48
54
  return p;
49
55
  }
50
56
 
57
+ //リストの先頭に挿入
51
58
  void slist_insert_head(slist L, slobj p){
52
59
  p -> next = L -> head;
53
60
  L -> head = p;
54
61
  }
55
62
 
63
+ //リストの末尾に挿入
56
64
  void slist_insert_tail(slist L, slobj p){
57
65
  if(L -> head == NULL){
58
66
  L -> tail = p;
@@ -68,6 +76,7 @@
68
76
  }
69
77
  }
70
78
 
79
+ //リストをプリント
71
80
  void slist_print(slist L)
72
81
  {
73
82
  slobj p;
@@ -79,6 +88,7 @@
79
88
  }
80
89
  }
81
90
 
91
+ //新しい疎行列を作成
82
92
  smatrix smatrix_new(int n, int m){
83
93
  smatrix S;
84
94
  int i;
@@ -91,9 +101,9 @@
91
101
  return S;
92
102
  }
93
103
 
104
+ //標準出力から行列を読み込み、別のメモリに記憶しておく
94
105
  smatrix smatrix_read(void){
95
106
  smatrix S;
96
- slobj p;
97
107
  int i, n, m, j;
98
108
  double v;
99
109
  scanf("%d", &n);
@@ -106,15 +116,14 @@
106
116
  break;
107
117
  }
108
118
  scanf("%lf", &v);
109
- p->j = j;
110
- p->v = v;
111
- p=slobj_new(j,v);
112
- slist_insert_tail(S.A[i], p);
119
+ slist_insert_tail(S.A[i], slobj_new(j ,v));
120
+ //このときslobj_newで確保したメモリがslist_freeで解放できていないようです
113
121
  }
114
122
  }
115
123
  return S;
116
124
  }
117
125
 
126
+ //疎行列をプリント
118
127
  void smatrix_print(smatrix S){
119
128
  int i;
120
129
  printf("%d ", S.n);
@@ -125,10 +134,11 @@
125
134
  }
126
135
  }
127
136
 
137
+ //疎行列の転置を作成・出力
128
138
  smatrix smatrix_transpose(smatrix S){
129
139
  int i, k;
130
140
  double x;
131
- slobj p, q;
141
+ slobj p;
132
142
  smatrix T;
133
143
  T = smatrix_new(S.m, S.n);
134
144
  for(i = 0; i <= S.n-1; i++){
@@ -139,14 +149,15 @@
139
149
  }
140
150
  k = p->j;
141
151
  x = p->v;
142
- q = slobj_new(i+1, x);
143
- slist_insert_tail(T.A[k-1], q);
152
+ slist_insert_tail(T.A[k-1], slobj_new(i+1, x));
153
+ //このときslobj_newで確保したメモリがslist_freeで解放できていないようです
144
154
  p = p->next;
145
155
  }
146
156
  }
147
157
  return T;
148
158
  }
149
159
 
160
+ //リストのメモリを解放
150
161
  void slist_free(slist L){
151
162
  slobj p, q, r;
152
163
  p = L->head;
@@ -160,27 +171,13 @@
160
171
  free(L);
161
172
  }
162
173
 
163
- void slist_freerows(slist *L){
174
+ //疎行列のメモリを解放(リストを順にfreeしているつもりです)
164
- slobj p, q, r;
165
- p = (*L) -> head;
166
- q = p->next;
167
- while (q != NULL){
168
- r = q;
169
- q = q-> next;
170
- free(p);
171
- p = r;
172
- }
173
- free(L);
174
- }
175
-
176
175
  void smatrix_free(smatrix S){
177
176
  int i;
178
177
  for(i = 0; i <= S.n-1; i++){
179
- if(S.A[i]->head != NULL){
180
178
  slist_free(S.A[i]);
181
- }
182
179
  }
183
- slist_freerows(S.A);
180
+ free(S.A);
184
181
  }
185
182
 
186
183
  int main(){
@@ -193,4 +190,52 @@
193
190
  smatrix_free(B);
194
191
  return 0;
195
192
  }
196
- ```
193
+ ```
194
+ valgrindでの出力は以下の通りでした。
195
+
196
+ ```valgrind
197
+ valgrind --leak-check=full ./a.out
198
+ ==152== Memcheck, a memory error detector
199
+ ==152== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
200
+ ==152== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
201
+ ==152== Command: ./a.out
202
+ ==152==
203
+ ==152== error calling PR_SET_PTRACER, vgdb might block
204
+ 2 3
205
+ 1 1.0 2 2.0 3 3.0 -1
206
+ 1 4.0 2 5.0 3 6.0 -1
207
+ 3 2
208
+ 1 1.000000 2 4.000000 -1
209
+ 1 2.000000 2 5.000000 -1
210
+ 1 3.000000 2 6.000000 -1
211
+ ==152==
212
+ ==152== HEAP SUMMARY:
213
+ ==152== in use at exit: 120 bytes in 5 blocks
214
+ ==152== total heap usage: 21 allocs, 16 frees, 8,600 bytes allocated
215
+ ==152==
216
+ ==152== 48 bytes in 2 blocks are definitely lost in loss record 1 of 2
217
+ ==152== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
218
+ ==152== by 0x1087F6: slobj_new (42.c:33)
219
+ ==152== by 0x108A5A: smatrix_read (42.c:97)
220
+ ==152== by 0x108CED: main (42.c:158)
221
+ ==152==
222
+ ==152== 72 bytes in 3 blocks are definitely lost in loss record 2 of 2
223
+ ==152== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
224
+ ==152== by 0x1087F6: slobj_new (42.c:33)
225
+ ==152== by 0x108BD2: smatrix_transpose (42.c:127)
226
+ ==152== by 0x108D08: main (42.c:159)
227
+ ==152==
228
+ ==152== LEAK SUMMARY:
229
+ ==152== definitely lost: 120 bytes in 5 blocks
230
+ ==152== indirectly lost: 0 bytes in 0 blocks
231
+ ==152== possibly lost: 0 bytes in 0 blocks
232
+ ==152== still reachable: 0 bytes in 0 blocks
233
+ ==152== suppressed: 0 bytes in 0 blocks
234
+ ==152==
235
+ ==152== For counts of detected and suppressed errors, rerun with: -v
236
+ ==152== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
237
+ ```
238
+
239
+ このように、smatrix_readやsmatrix_transposesmatrix_freeで新しい行列を作成し、そこに順次リストの要素を挿入していく際に確保したリスト要素のメモリはsmatrix_freeやその中のslist_freeで全て解放しているはずなのですが、どうやら全部解放しきれていないようです。(問題がありそうな個所はコードの中でその旨をコメントしておきました)
240
+
241
+ slist_freeの記述がおかしいのでしょうか。