質問編集履歴

2

誤字修正

2020/04/27 00:53

投稿

aardvark
aardvark

スコア17

test CHANGED
File without changes
test CHANGED
@@ -474,7 +474,7 @@
474
474
 
475
475
 
476
476
 
477
- このように、smatrix_readやsmatrix_transposesmatrix_freeで新しい行列を作成し、そこに順次リストの要素を挿入していく際に確保したリスト要素のメモリはsmatrix_freeやその中のslist_freeで全て解放しているはずなのですが、どうやら全部解放しきれていないようです。(問題がありそうな個所はコードの中でその旨をコメントしておきました)
477
+ このように、smatrix_readやsmatrix_transposesで新しい行列を作成し、そこに順次リストの要素を挿入していく際に確保したリスト要素のメモリはsmatrix_freeやその中のslist_freeで全て解放しているはずなのですが、どうやら全部解放しきれていないようです。(問題がありそうな個所はコードの中でその旨をコメントしておきました)
478
478
 
479
479
 
480
480
 

1

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

2020/04/27 00:53

投稿

aardvark
aardvark

スコア17

test CHANGED
File without changes
test CHANGED
@@ -18,6 +18,8 @@
18
18
 
19
19
 
20
20
 
21
+ 編集:コードが長ったらしい上に、実際valgrindでどういう出力があったのかについては全く言及しておりませんでしたね。大変失礼いたしました。
22
+
21
23
  ```C
22
24
 
23
25
  #include <stdio.h>
@@ -28,9 +30,11 @@
28
30
 
29
31
 
30
32
 
31
- #define NEW(p, n){p = malloc((n)*sizeof(p[0]));}
33
+ #define NEW(p, n){p = malloc((n)*sizeof(p[0]));} //動的メモリ確保の関数
34
+
35
+
36
+
32
-
37
+ //リストの要素の構造体
33
-
34
38
 
35
39
  typedef struct slobj_{
36
40
 
@@ -44,6 +48,8 @@
44
48
 
45
49
 
46
50
 
51
+ //リストの構造体
52
+
47
53
  typedef struct{
48
54
 
49
55
  slobj head;
@@ -54,15 +60,19 @@
54
60
 
55
61
 
56
62
 
63
+ //疎行列の構造体(リストの配列ということ)
64
+
57
65
  typedef struct{
58
66
 
59
67
  int n,m;
60
68
 
61
69
  slist* A;
62
70
 
63
- } smatrix;
71
+ } smatrix; 
72
+
73
+
74
+
64
-
75
+ //新しいリストを作成
65
-
66
76
 
67
77
  slist slist_new(void){
68
78
 
@@ -80,6 +90,8 @@
80
90
 
81
91
 
82
92
 
93
+ //新しいリストの要素を作成
94
+
83
95
  slobj slobj_new(int x, double y){
84
96
 
85
97
  slobj p;
@@ -98,6 +110,8 @@
98
110
 
99
111
 
100
112
 
113
+ //リストの先頭に挿入
114
+
101
115
  void slist_insert_head(slist L, slobj p){
102
116
 
103
117
  p -> next = L -> head;
@@ -108,6 +122,8 @@
108
122
 
109
123
 
110
124
 
125
+ //リストの末尾に挿入
126
+
111
127
  void slist_insert_tail(slist L, slobj p){
112
128
 
113
129
  if(L -> head == NULL){
@@ -138,6 +154,8 @@
138
154
 
139
155
 
140
156
 
157
+ //リストをプリント
158
+
141
159
  void slist_print(slist L)
142
160
 
143
161
  {
@@ -160,6 +178,8 @@
160
178
 
161
179
 
162
180
 
181
+ //新しい疎行列を作成
182
+
163
183
  smatrix smatrix_new(int n, int m){
164
184
 
165
185
  smatrix S;
@@ -184,185 +204,159 @@
184
204
 
185
205
 
186
206
 
207
+ //標準出力から行列を読み込み、別のメモリに記憶しておく
208
+
187
209
  smatrix smatrix_read(void){
188
210
 
189
211
  smatrix S;
190
212
 
213
+ int i, n, m, j;
214
+
215
+ double v;
216
+
217
+ scanf("%d", &n);
218
+
219
+ scanf("%d", &m);
220
+
221
+ S = smatrix_new(n, m);
222
+
223
+ for(i = 0; i <= n-1; i++){
224
+
225
+ while(1){
226
+
227
+ scanf("%d", &j);
228
+
229
+ if (j < 0){
230
+
231
+ break;
232
+
233
+ }
234
+
235
+ scanf("%lf", &v);
236
+
237
+ slist_insert_tail(S.A[i], slobj_new(j ,v));
238
+
239
+ //このときslobj_newで確保したメモリがslist_freeで解放できていないようです
240
+
241
+ }
242
+
243
+ }
244
+
245
+ return S;
246
+
247
+ }
248
+
249
+
250
+
251
+ //疎行列をプリント
252
+
253
+ void smatrix_print(smatrix S){
254
+
255
+ int i;
256
+
257
+ printf("%d ", S.n);
258
+
259
+ printf("%d\n", S.m);
260
+
261
+ for(i = 0; i <= S.n-1; i++){
262
+
263
+ slist_print(S.A[i]);
264
+
265
+ printf("%d\n", -1);
266
+
267
+ }
268
+
269
+ }
270
+
271
+
272
+
273
+ //疎行列の転置を作成・出力
274
+
275
+ smatrix smatrix_transpose(smatrix S){
276
+
277
+ int i, k;
278
+
279
+ double x;
280
+
191
281
  slobj p;
192
282
 
193
- int i, n, m, j;
194
-
195
- double v;
283
+ smatrix T;
196
-
197
- scanf("%d", &n);
284
+
198
-
199
- scanf("%d", &m);
200
-
201
- S = smatrix_new(n, m);
285
+ T = smatrix_new(S.m, S.n);
202
-
286
+
203
- for(i = 0; i <= n-1; i++){
287
+ for(i = 0; i <= S.n-1; i++){
288
+
289
+ p = S.A[i]->head;
204
290
 
205
291
  while(1){
206
292
 
207
- scanf("%d", &j);
208
-
209
- if (j < 0){
293
+ if(p==NULL){
210
-
294
+
211
- break;
295
+ break;
212
-
296
+
213
- }
297
+ }
214
-
215
- scanf("%lf", &v);
298
+
216
-
217
- p->j = j;
299
+ k = p->j;
218
-
300
+
219
- p->v = v;
301
+ x = p->v;
220
-
221
- p=slobj_new(j,v);
302
+
222
-
223
- slist_insert_tail(S.A[i], p);
303
+ slist_insert_tail(T.A[k-1], slobj_new(i+1, x));
304
+
305
+ //このときslobj_newで確保したメモリがslist_freeで解放できていないようです
306
+
307
+ p = p->next;
224
308
 
225
309
  }
226
310
 
227
311
  }
228
312
 
229
- return S;
313
+ return T;
230
-
314
+
231
- }
315
+ }
316
+
317
+
318
+
232
-
319
+ //リストのメモリを解放
320
+
233
-
321
+ void slist_free(slist L){
322
+
234
-
323
+ slobj p, q, r;
324
+
325
+ p = L->head;
326
+
327
+ q = p->next;
328
+
329
+ while (q != NULL){
330
+
331
+ r = q;
332
+
333
+ q = q-> next;
334
+
335
+ free(p);
336
+
337
+ p = r;
338
+
339
+ }
340
+
341
+ free(L);
342
+
343
+ }
344
+
345
+
346
+
347
+ //疎行列のメモリを解放(リストを順にfreeしているつもりです)
348
+
235
- void smatrix_print(smatrix S){
349
+ void smatrix_free(smatrix S){
236
350
 
237
351
  int i;
238
352
 
239
- printf("%d ", S.n);
240
-
241
- printf("%d\n", S.m);
242
-
243
353
  for(i = 0; i <= S.n-1; i++){
244
354
 
245
- slist_print(S.A[i]);
246
-
247
- printf("%d\n", -1);
248
-
249
- }
250
-
251
- }
252
-
253
-
254
-
255
- smatrix smatrix_transpose(smatrix S){
256
-
257
- int i, k;
258
-
259
- double x;
260
-
261
- slobj p, q;
262
-
263
- smatrix T;
264
-
265
- T = smatrix_new(S.m, S.n);
266
-
267
- for(i = 0; i <= S.n-1; i++){
268
-
269
- p = S.A[i]->head;
270
-
271
- while(1){
272
-
273
- if(p==NULL){
274
-
275
- break;
276
-
277
- }
278
-
279
- k = p->j;
280
-
281
- x = p->v;
282
-
283
- q = slobj_new(i+1, x);
284
-
285
- slist_insert_tail(T.A[k-1], q);
286
-
287
- p = p->next;
288
-
289
- }
290
-
291
- }
292
-
293
- return T;
294
-
295
- }
296
-
297
-
298
-
299
- void slist_free(slist L){
300
-
301
- slobj p, q, r;
302
-
303
- p = L->head;
304
-
305
- q = p->next;
306
-
307
- while (q != NULL){
308
-
309
- r = q;
310
-
311
- q = q-> next;
312
-
313
- free(p);
314
-
315
- p = r;
316
-
317
- }
318
-
319
- free(L);
320
-
321
- }
322
-
323
-
324
-
325
- void slist_freerows(slist *L){
326
-
327
- slobj p, q, r;
328
-
329
- p = (*L) -> head;
330
-
331
- q = p->next;
332
-
333
- while (q != NULL){
334
-
335
- r = q;
336
-
337
- q = q-> next;
338
-
339
- free(p);
340
-
341
- p = r;
342
-
343
- }
344
-
345
- free(L);
346
-
347
- }
348
-
349
-
350
-
351
- void smatrix_free(smatrix S){
352
-
353
- int i;
354
-
355
- for(i = 0; i <= S.n-1; i++){
356
-
357
- if(S.A[i]->head != NULL){
358
-
359
355
  slist_free(S.A[i]);
360
356
 
361
- }
357
+ }
362
-
363
- }
358
+
364
-
365
- slist_freerows(S.A);
359
+ free(S.A);
366
360
 
367
361
  }
368
362
 
@@ -389,3 +383,99 @@
389
383
  }
390
384
 
391
385
  ```
386
+
387
+ valgrindでの出力は以下の通りでした。
388
+
389
+
390
+
391
+ ```valgrind
392
+
393
+ valgrind --leak-check=full ./a.out
394
+
395
+ ==152== Memcheck, a memory error detector
396
+
397
+ ==152== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
398
+
399
+ ==152== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
400
+
401
+ ==152== Command: ./a.out
402
+
403
+ ==152==
404
+
405
+ ==152== error calling PR_SET_PTRACER, vgdb might block
406
+
407
+ 2 3
408
+
409
+ 1 1.0 2 2.0 3 3.0 -1
410
+
411
+ 1 4.0 2 5.0 3 6.0 -1
412
+
413
+ 3 2
414
+
415
+ 1 1.000000 2 4.000000 -1
416
+
417
+ 1 2.000000 2 5.000000 -1
418
+
419
+ 1 3.000000 2 6.000000 -1
420
+
421
+ ==152==
422
+
423
+ ==152== HEAP SUMMARY:
424
+
425
+ ==152== in use at exit: 120 bytes in 5 blocks
426
+
427
+ ==152== total heap usage: 21 allocs, 16 frees, 8,600 bytes allocated
428
+
429
+ ==152==
430
+
431
+ ==152== 48 bytes in 2 blocks are definitely lost in loss record 1 of 2
432
+
433
+ ==152== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
434
+
435
+ ==152== by 0x1087F6: slobj_new (42.c:33)
436
+
437
+ ==152== by 0x108A5A: smatrix_read (42.c:97)
438
+
439
+ ==152== by 0x108CED: main (42.c:158)
440
+
441
+ ==152==
442
+
443
+ ==152== 72 bytes in 3 blocks are definitely lost in loss record 2 of 2
444
+
445
+ ==152== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
446
+
447
+ ==152== by 0x1087F6: slobj_new (42.c:33)
448
+
449
+ ==152== by 0x108BD2: smatrix_transpose (42.c:127)
450
+
451
+ ==152== by 0x108D08: main (42.c:159)
452
+
453
+ ==152==
454
+
455
+ ==152== LEAK SUMMARY:
456
+
457
+ ==152== definitely lost: 120 bytes in 5 blocks
458
+
459
+ ==152== indirectly lost: 0 bytes in 0 blocks
460
+
461
+ ==152== possibly lost: 0 bytes in 0 blocks
462
+
463
+ ==152== still reachable: 0 bytes in 0 blocks
464
+
465
+ ==152== suppressed: 0 bytes in 0 blocks
466
+
467
+ ==152==
468
+
469
+ ==152== For counts of detected and suppressed errors, rerun with: -v
470
+
471
+ ==152== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
472
+
473
+ ```
474
+
475
+
476
+
477
+ このように、smatrix_readやsmatrix_transposesmatrix_freeで新しい行列を作成し、そこに順次リストの要素を挿入していく際に確保したリスト要素のメモリはsmatrix_freeやその中のslist_freeで全て解放しているはずなのですが、どうやら全部解放しきれていないようです。(問題がありそうな個所はコードの中でその旨をコメントしておきました)
478
+
479
+
480
+
481
+ slist_freeの記述がおかしいのでしょうか。