2017-11-18 136 views
-1

我在寫一個迷宮問題程序。我可以成功地獲得路徑的方向。但是,我肯定會失去valgrind報告的錯誤。我的代碼中有什麼問題?Valgrind:在C程序中肯定會丟失內存泄漏

以下是我的代碼:

002: #include <stdio.h> 
003: #include <stdlib.h> 
004: #include <string.h> 
005: 
006: struct each_path { 
007:  int step_nums, coin_nums; 
008:  char **step_dir; 
009: }; 
010: 
011: void initial_value(); 
012: void *readFile(char *fileName); 
013: void maze_1Dto2D(char *array); 
014: void visit(int, int); 
015: void display_direction(); 
016: struct each_path *epath; 
017: int path_assume_num; 
018: char *maze1D, **maze2D, **maze2D_tmp; 
019: int maze_height, maze_width; 
020: int startI = 1, startJ = 1, endI, endJ; // entrance & exit 
021: int path_nums, coin_nums, min_step_num, min_path_num; 
022: 
023: 
024: int main(void) { 
025:  char *maze_txtfile; 
026:  int i, j; 
027: 
028:  // the first maze 
029:  initial_value(); 
030:  maze_txtfile = readFile("maze2.txt"); 
031:  maze2D_tmp = malloc(maze_height * sizeof(*maze2D_tmp)); 
032:  for (i = 0; i < maze_height; ++i) { 
033:   maze2D_tmp[i] = malloc(maze_width + 1); 
034:   memcpy(maze2D_tmp[i], maze2D[i], maze_width + 1); 
035:  } 
036:  epath = malloc(path_assume_num * sizeof(*epath)); 
037:  for (i = 0; i < path_assume_num; ++i) { 
038:   epath[i].step_dir = malloc(10 * sizeof(*epath[i].step_dir)); 
039:   for (j = 0; j < 10; ++j) 
040:    epath[i].step_dir[j] = malloc(6); 
041:  } 
042: 
043:  endI = maze_height - 2; 
044:  endJ = maze_width - 2; 
045:  visit(startI, startJ); 
046:  display_direction(); 
047: 
048:  for (i = 0; i < path_nums; ++i) { 
049:   for (j = 0; j < epath[i].step_nums; ++j) 
050:    free(epath[i].step_dir[j]); 
051:   free(epath[i].step_dir); 
052:  } 
053:  for (i = 0; i < maze_height; ++i) { 
054:   free(maze2D[i]); 
055:   free(maze2D_tmp[i]); 
056:  } 
057:  free(maze1D); 
058:  free(maze2D); 
059:  free(maze2D_tmp); 
060:  free(epath); 
061: 
062:  exit(0); 
063: } 
064: 
065: void initial_value() { 
066:  path_assume_num = 1; 
067:  maze_height = 0; 
068:  maze_width = 0; 
069:  path_nums = 0; 
070:  coin_nums = 0; 
071:  min_step_num = 100000; 
072: } 
073: 
074: 
075: void *readFile(char *fileName) { 
076:  FILE *file = fopen(fileName, "r"); 
077:  size_t maze_unit_num = 0, maze_assume_size = 100; 
078:  int maze_unit; 
079: 
080:  if (file == NULL) 
081:   return NULL; //could not open file 
082: 
083:  maze1D = malloc(maze_assume_size); 
084: 
085:  while ((maze_unit = fgetc(file)) != EOF) 
086:  { 
087:   if (maze_unit_num >= maze_assume_size) 
088:   { 
089:    maze_assume_size *= 2; 
090:    maze1D = realloc(maze1D, maze_assume_size); 
091:   } 
092:   maze1D[maze_unit_num] = (char) maze_unit; 
093: 
094:   if (maze1D[maze_unit_num] == '\n') 
095:   { 
096:    if (maze_height == 0) 
097:     maze_width = maze_unit_num - 1; 
098:    maze_height++; 
099:   } 
100:   maze_unit_num++; 
101:  } 
102:  maze1D = realloc(maze1D, maze_unit_num + 1); 
103:  maze1D[maze_unit_num] = '\0'; 
104:  maze_1Dto2D(maze1D); 
105: } 
106: 
107: void maze_1Dto2D(char *array) { 
108:  size_t i = 0, j = 0, num = 0; 
109:  maze2D = malloc(maze_height * sizeof(*maze2D)); 
110: 
111:  for (i = 0; i < maze_height ; ++i) 
112:  { 
113:   maze2D[i] = malloc(maze_width + 1); 
114:   for (j = 0; j < maze_width + 1; ++j, ++num) 
115:   { 
116:    maze2D[i][j] = array[num]; 
117: 
118:    if (array[num] == '\r') 
119:     --j; 
120:    else if (array[num] == '\n') 
121:     maze2D[i][j] = '\0'; 
122:    else 
123:     maze2D[i][j] = array[num]; 
124:   } 
125:  } 
126: } 
127: 
128: void visit(int i, int j) { 
129:  int preI, preJ, curI = 1, curJ = 1; 
130:  int step_nums = 0, step_assume_num = 10; // entrance is not included 
131:  char dir[6]; 
132:  int m, n; 
133: 
134:  if (maze2D_tmp[i][j] == '2') 
135:   coin_nums++; 
136:  maze2D_tmp[i][j] = '3'; 
137:  if (i == endI && j == endJ) { 
138:   if (path_nums >= path_assume_num) { 
139:    path_assume_num *= 2; 
140:    epath = realloc(epath, path_assume_num * sizeof(*epath)); 
141:    for (m = path_assume_num/2; m < path_assume_num; ++m) { 
142:     epath[m].step_dir = malloc(10 * sizeof(*epath[m].step_dir)); 
143:     for (n = 0; n < 10; ++n) 
144:      epath[m].step_dir[n] = malloc(6); 
145:    } 
146:   } 
147:   while (curI != endI || curJ != endJ) 
148:   { 
149:    if (step_nums >= step_assume_num) { 
150:     step_assume_num *= 2; 
151:     epath[path_nums].step_dir = realloc(epath[path_nums].step_dir, step_assume_num * sizeof(*epath[path_nums].step_dir)); 
152:     for (m = step_assume_num/2; m < step_assume_num; ++m) 
153:      epath[path_nums].step_dir[m] = malloc(6); 
154:    } 
155: 
156:    if (maze2D_tmp[curI][curJ + 1] == '3' && preJ != (curJ + 1)) { 
157:     preI = curI; 
158:     preJ = curJ; 
159:     curJ++; 
160:     strcpy(dir, "right"); 
161: 
162:    } 
163:    else if (maze2D_tmp[curI + 1][curJ] == '3' && preI != (curI + 1)) { 
164:     preI = curI; 
165:     preJ = curJ; 
166:     curI++; 
167:     strcpy(dir, "down"); 
168:    } 
169:    else if (maze2D_tmp[curI - 1][curJ] == '3' && preI != (curI - 1)) { 
170:     preI = curI; 
171:     preJ = curJ; 
172:     curI--; 
173:     strcpy(dir, "up"); 
174:    } 
175:    else if (maze2D_tmp[curI][curJ - 1] == '3' && preJ != (curJ - 1)) { 
176:     preI = curI; 
177:     preJ = curJ; 
178:     curJ--; 
179:     strcpy(dir, "left"); 
180:    } 
181:    strcpy(epath[path_nums].step_dir[step_nums], dir); 
182:    step_nums++; 
183:   } 
184:   epath[path_nums].step_dir = realloc(epath[path_nums].step_dir, step_nums * sizeof(*epath[path_nums].step_dir)); 
185:   epath[path_nums].step_nums = step_nums; 
186:   epath[path_nums].coin_nums = coin_nums; 
187:   path_nums++; 
188:   if (step_nums < min_step_num) 
189:   { 
190:    min_step_num = step_nums; 
191:    min_path_num = path_nums; 
192:   } 
193:  } 
194: 
195:  if (maze2D_tmp[i][j + 1] == '1' || maze2D_tmp[i][j + 1] == '2') visit(i, j + 1); 
196:  if (maze2D_tmp[i + 1][j] == '1' || maze2D_tmp[i + 1][j] == '2') visit(i + 1, j); 
197:  if (maze2D_tmp[i][j - 1] == '1' || maze2D_tmp[i][j - 1] == '2') visit(i, j - 1); 
198:  if (maze2D_tmp[i - 1][j] == '1' || maze2D_tmp[i - 1][j] == '2') visit(i - 1, j); 
199: 
200:  if (maze2D[i][j] == '2') 
201:  { 
202:   maze2D_tmp[i][j] = '2'; 
203:   coin_nums--; 
204:  } 
205:  else 
206:   maze2D_tmp[i][j] = '1'; 
207: } 
208: 
209: void display_direction() { 
210:  int i; 
211:  for (i = 0; i < min_step_num; ++i) 
212:   printf("%s\n", epath[min_path_num - 1].step_dir[i]); 
213:  printf("coin numbers:%d\n", epath[min_path_num - 1].coin_nums); 
214: } 
Valgrind的報告:

我得到 「肯定失去了:1908個字節,318塊」,從泄漏總結,並從4個上下文( 4個錯誤抑制:0 0 )從錯誤摘要。 什麼可能會導致這些錯誤消息?

==3410== HEAP SUMMARY: 
==3410==  in use at exit: 2,460 bytes in 319 blocks 
==3410== total heap usage: 742 allocs, 423 frees, 37,249 bytes allocated 
==3410== 
==3410== 954 bytes in 159 blocks are definitely lost in loss record 2 of 3 
==3410== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3410== by 0x401007: visit (4thesecondmaze.c:153) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x4012EC: visit (4thesecondmaze.c:195) 
==3410== by 0x4012EC: visit (4thesecondmaze.c:195) 
==3410== by 0x4012EC: visit (4thesecondmaze.c:195) 
==3410== 
==3410== 954 bytes in 159 blocks are definitely lost in loss record 3 of 3 
==3410== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3410== by 0x401007: visit (4thesecondmaze.c:153) 
==3410== by 0x4012EC: visit (4thesecondmaze.c:195) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x4013BA: visit (4thesecondmaze.c:197) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x401352: visit (4thesecondmaze.c:196) 
==3410== by 0x4012EC: visit (4thesecondmaze.c:195) 
==3410== 
==3410== LEAK SUMMARY: 
==3410== definitely lost: 1,908 bytes in 318 blocks 
==3410== indirectly lost: 0 bytes in 0 blocks 
==3410==  possibly lost: 0 bytes in 0 blocks 
==3410== still reachable: 552 bytes in 1 blocks 
==3410==   suppressed: 0 bytes in 0 blocks 
==3410== Reachable blocks (those to which a pointer was found) are not shown. 
==3410== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0) 
+1

第153行:'epath [path_nums] .step_dir [m] = malloc(6);' - 你認爲你在哪裏釋放內存? Valgrind認爲你不會釋放它 - 這可能是對的。那個'malloc()'調用中的'6'也令人擔憂。 –

+0

@JonathanLeffler:從第48行到第52行? – linpohsien

+0

@JonathanLeffler:這個怎麼樣?'epath [i] .step_dir [j] = malloc(6 * sizeof * epath [i] .step_dir);' – linpohsien

回答

3

在153行,你分配了一堆內存塊到step_dir,並與step_assume_num分配的塊結束。

稍後,在184行上,您可以撥打reallocstep_dir的分配內存減少到實際使用的數量,step_num塊。分配但未使用的塊(從step_num + 1step_assume_num)尚未釋放。您需要釋放這些塊,然後再減小數組大小。