質問編集履歴
2
誤字修正
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や
|
239
|
+
このように、smatrix_readやsmatrix_transposesで新しい行列を作成し、そこに順次リストの要素を挿入していく際に確保したリスト要素のメモリはsmatrix_freeやその中のslist_freeで全て解放しているはずなのですが、どうやら全部解放しきれていないようです。(問題がありそうな個所はコードの中でその旨をコメントしておきました)
|
240
240
|
|
241
241
|
slist_freeの記述がおかしいのでしょうか。
|
1
コードを編集し、valgrindを使ってデバッグした結果を追加しました
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],
|
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
|
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],
|
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
|
-
|
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
|
-
|
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の記述がおかしいのでしょうか。
|