Please help! Unknown memory leak with linked list nodes...

Please support our C advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved

Join Date: Sep 2007
Posts: 16
Reputation: RaDeuX is an unknown quantity at this point 
Solved Threads: 0
RaDeuX RaDeuX is offline Offline
Newbie Poster

Please help! Unknown memory leak with linked list nodes...

 
0
  #1
Dec 7th, 2008
Okay, so my program is very close to completion. The only problem is that the program leaks memory. The deleteNode, deleteManager, and destroyList are the ones to blame, or so I think. When I delete a node other than the first one it works while leaking memory. However, when I try deleting the first node and then try to display the list again, the program crashes. Perhaps my deleteNode function needs some readjustment. In any case, here is the code and the input file.
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<ctype.h>
  5. #include<crtdbg.h>
  6.  
  7. #define FLUSH while (getchar () != '\n')
  8. #define FILE_IN "countries.txt"
  9.  
  10. // Type Definitions
  11.  
  12. typedef char KEY_TYPE;
  13. typedef struct {
  14. char *name;
  15. char *capital;
  16. long population;
  17. } COUNTRY;
  18.  
  19. typedef struct {
  20. KEY_TYPE key[3];
  21. COUNTRY list;
  22. } DATA;
  23.  
  24. typedef struct nodeTag {
  25. DATA data;
  26. struct nodeTag* link;
  27. } NODE;
  28.  
  29. // Prototype Declarations
  30. char getOption (void);
  31. void printMenu (void);
  32.  
  33. int searchList (NODE *pList, NODE **pPre, NODE **pCur, char target[]);
  34. NODE *insertNode (NODE *pList, NODE *pPre, DATA item);
  35. NODE *deleteNode (NODE *pList, NODE *pPre, NODE *pCur);
  36. void printList (NODE *pList);
  37. NODE *destroyList (NODE *pList);
  38.  
  39. NODE *buildList (void);
  40.  
  41. NODE *processListManager (NODE *pList);
  42. void searchManager (NODE *pList);
  43. NODE *insertManager (NODE *pList);
  44. NODE *deleteManager (NODE *pList);
  45.  
  46. int getData ( FILE *spIn, DATA *data );
  47. void insertCommas ( NODE *pWalker, char *population );
  48. void printCountry ( NODE *list, char populationInCommas[] );
  49. int insertHandler ( DATA *data, char target[] );
  50.  
  51. int main ( void )
  52. {
  53. // Local Definitions
  54. NODE *list = NULL;
  55.  
  56. // Statements
  57. printf("\t\t LAB 8 - LINKED LISTS\n\n");
  58.  
  59. list = buildList();
  60. printMenu();
  61. processListManager ( list );
  62. list = destroyList ( list );
  63.  
  64. printf("\n\t\tEnd of LAB 8 - LINKED LISTS"
  65. "\n\t\tHave a great day!\n");
  66.  
  67.  
  68. printf( _CrtDumpMemoryLeaks() ? "Memory Leak\n" : "No Leak\n");
  69.  
  70. return 0;
  71.  
  72. }// main
  73.  
  74. /* ==================== getOption ====================
  75. Gets and validates the user's option.
  76. Pre : nothing
  77. Post : valid option returned
  78. */
  79. char getOption (void)
  80. {
  81. // Local Definitions
  82. char option;
  83.  
  84. // Statements
  85. printf ("\n\nPlease enter the option: ");
  86. scanf ("%c", &option);
  87. FLUSH;
  88. option = toupper (option);
  89. while(strchr("LSIDME", option) == NULL)
  90. {
  91. printf("\a*** Invalid option! ***\n");
  92. printf("Enter one of the following letters: L, S, I, D, M, E: " );
  93. scanf ("%c", &option);
  94. FLUSH;
  95. option = toupper (option);
  96. }
  97.  
  98. return option;
  99.  
  100. } // getOption
  101.  
  102. /* ============================== printMenu ==============================
  103. Prints the menu to the screen.
  104. PRE : nothing
  105. POST : menu printed
  106. */
  107. void printMenu (void)
  108. {
  109. // Local Definitions
  110.  
  111. // Statements
  112. printf("\n\t\t**********************"
  113. "\n\t\t* *"
  114. "\n\t\t* L - List *"
  115. "\n\t\t* S - Search *"
  116. "\n\t\t* I - Insert *"
  117. "\n\t\t* D - Delete *"
  118. "\n\t\t* M - Print Menu *"
  119. "\n\t\t* E - Exit *"
  120. "\n\t\t* *"
  121. "\n\t\t**********************");
  122.  
  123. return;
  124.  
  125. } // printMenu
  126.  
  127. /* ============================== processListManager ====================
  128. Process user's option by calling appropriate functions.
  129. PRE : pList - a pointer to the first node of a linked list
  130. POST : pList - might be changed after inserting or deleting
  131. */
  132.  
  133. NODE *processListManager (NODE *pList)
  134. {
  135. // Local Definitions
  136. char option;
  137.  
  138. // Statements
  139. do
  140. {
  141. option = getOption();
  142. switch(option)
  143. {
  144. case 'L' : printList (pList);
  145. break;
  146. case 'S' : searchManager (pList);
  147. break;
  148. case 'I' : pList = insertManager (pList);
  149. break;
  150. case 'D' : pList = deleteManager (pList);
  151. break;
  152. case 'M' : printMenu ();
  153. break;
  154. case 'E' : printf("End of processing!\n");
  155. break;
  156. default : break;
  157. }
  158. } while (option != 'E');
  159.  
  160. return pList;
  161.  
  162. } // processListManager
  163.  
  164. NODE *buildList (void)
  165. {
  166. // Local Declarations
  167. NODE *pList;
  168. NODE *pPre;
  169. NODE *pCur;
  170. DATA data;
  171. FILE *spIn;
  172. int result;
  173.  
  174. // Statements
  175. if ( ! ( spIn = fopen ( FILE_IN, "r" ) ) ) {
  176. printf("Error opening file %s\n", FILE_IN);
  177. exit(100);
  178. }
  179. pList = NULL;
  180. while ( getData ( spIn, &data ) ) {
  181. result = searchList(pList, &pPre, &pCur, data.key);
  182. if ( !result )
  183. pList = insertNode(pList, pPre, data);
  184. }
  185. fclose ( spIn );
  186. return pList;
  187. } // buildList
  188.  
  189. int getData ( FILE *spIn, DATA *data )
  190. {
  191. // Local Declarations
  192. int result;
  193.  
  194. // Statements
  195. data->list.name = (char*)calloc(21, sizeof(char));
  196. data->list.capital = (char*)calloc(16, sizeof(char));
  197. result = fscanf ( spIn, "%2s %20[^;] %*c %15[^;] %*c %ld",
  198. data->key, data->list.name,
  199. data->list.capital, &(data->list.population) );
  200. if ( result == 4 )
  201. return 1;
  202. else {
  203. free ( data->list.name );
  204. free ( data->list.capital );
  205. return 0;
  206. }
  207. } // getData
  208.  
  209. NODE *insertNode (NODE *pList, NODE *pPre, DATA item)
  210. {
  211. // Local Declarations
  212. NODE *pNew;
  213.  
  214. // Statements
  215. if ( ! ( pNew = (NODE*)malloc(sizeof(NODE))))
  216. printf("Memory is unavailable.\n"),
  217. exit(200);
  218. pNew->data = item;
  219. if ( pPre == NULL ) {
  220. pNew->link = pList;
  221. pList = pNew;
  222. }
  223. else {
  224. pNew->link = pPre->link;
  225. pPre->link = pNew;
  226. }
  227. return pList;
  228. } // insertNode
  229.  
  230. int searchList (NODE *pList, NODE **pPre, NODE **pCur, char target[])
  231. {
  232. // Local Declarations
  233. int found = 0;
  234.  
  235. // Statements
  236. *pPre = NULL;
  237. *pCur = pList;
  238. while (*pCur != NULL) {
  239. if (strcmp ( target, (*pCur)->data.key) == 0 ){
  240. found = 1;
  241. break;
  242. }
  243. *pPre = *pCur;
  244. *pCur = (*pCur)->link;
  245. }
  246. return found;
  247. } // searchList
  248.  
  249. void printList (NODE *pList)
  250. {
  251. // Local Declarations
  252. NODE *pWalker;
  253. // Statements
  254. printf( "== ====================\n"
  255. "ID NAME \n"
  256. "== ====================\n");
  257. pWalker = pList;
  258. while ( pWalker ) {
  259. printf("%s %-20s\n",
  260. pWalker->data.key, pWalker->data.list.name);
  261. pWalker = pWalker->link;
  262. }
  263. printf( "=======================" );
  264. return;
  265. } // printList
  266.  
  267. void insertCommas ( NODE *pWalker, char *population )
  268. {
  269. // Local Declarations
  270. char printString[15];
  271. char tempString[15];
  272. char insertComma[] = ",";
  273. int strLength;
  274. int checkRmdr;
  275. int i;
  276. // Statements
  277. *printString = '\0';
  278. sprintf(tempString, "%ld", pWalker->data.list.population);
  279. strLength = strlen ( tempString );
  280. checkRmdr = strLength % 3;
  281. if ( checkRmdr > 0 ) {
  282. strncat ( printString, tempString, checkRmdr );
  283. strcat ( printString, insertComma );
  284. }
  285. for ( i = checkRmdr; i < (int) strlen ( tempString ); ) {
  286. strncat ( printString, tempString + i, 3 );
  287. i += 3;
  288. strcat ( printString, insertComma );
  289. }
  290. printString[strlen(printString) - 1] = '\0';
  291. strcpy (population, printString);
  292. return;
  293. } // insertCommas
  294.  
  295. void searchManager (NODE *pList)
  296. {
  297. // Local Declarations
  298. NODE *pPre;
  299. NODE *pCur;
  300. char target[3];
  301. char populationInCommas[15];
  302.  
  303. // Statements
  304. printf("Please enter a key: ");
  305. scanf("%2s", target);
  306. FLUSH;
  307. if ( searchList ( pList, &pPre, &pCur, target ) ) {
  308. insertCommas(pCur, populationInCommas);
  309. printCountry(pCur, populationInCommas);
  310. }
  311. else
  312. printf("Country could not be found. Please try again.");
  313. return;
  314. } // searchManager
  315.  
  316. void printCountry ( NODE *list, char populationInCommas[] )
  317. {
  318. // Statements
  319. printf( "\n ID: %s\n"
  320. " Name: %s\n"
  321. " Capital: %s\n"
  322. "Population: %s\n", list->data.key,
  323. list->data.list.name,
  324. list->data.list.capital,
  325. populationInCommas);
  326. } // printCountry
  327.  
  328. NODE *insertManager (NODE *pList)
  329. {
  330. // Local Declarations
  331. NODE *pPre;
  332. NODE *pCur;
  333. DATA insertData;
  334. int position;
  335. char target[3];
  336. int counter = 1;
  337. // Statements
  338. printf("Please enter a key: ");
  339. scanf("%2s", target);
  340. FLUSH;
  341. if ( ! ( searchList ( pList, &pPre, &pCur, target ) ) ) {
  342. position = insertHandler ( &insertData, target );
  343.  
  344. switch (position) {
  345. case 1: pPre = NULL;
  346. break;
  347. case 2: pPre = pList;
  348. while (pPre) {
  349. pPre = pPre->link;
  350. counter++;
  351. }
  352. counter /= 2;
  353. pPre = pList;
  354. while ( counter != 1 ) {
  355. pPre = pPre->link;
  356. counter--;
  357. }
  358. break;
  359. case 3: pPre->link = NULL;
  360. break;
  361. }
  362. pList = insertNode( pList, pPre, insertData );
  363. }
  364. else
  365. printf("That country ID already exists. Please try again.");
  366. return pList;
  367. }
  368.  
  369. int insertHandler ( DATA *data, char target[] )
  370. {
  371. // Local Declarations
  372. int position = 0;
  373.  
  374. // Statements
  375. if ( ! ( data->list.name = (char*)calloc(21, sizeof(char)))) {
  376. printf("Memory Unavailable.\n");
  377. exit(300);
  378. }
  379. if ( ! ( data->list.capital = (char*)calloc(16, sizeof(char)))) {
  380. printf("Memory Unavailable.\n");
  381. exit(400);
  382. }
  383. strcpy ( data->key, target );
  384. printf("Enter the country's name: ");
  385. scanf("%s", data->list.name);
  386. FLUSH;
  387. printf("Enter the country's capital: ");
  388. scanf("%s", data->list.capital);
  389. FLUSH;
  390. printf("Enter the country's population: ");
  391. scanf("%ld", &(data->list.population));
  392. FLUSH;
  393. while ( position < 1 || position > 3 ) {
  394. printf("Where would you like to place this new country?\n"
  395. "Beginning(1), Middle(2), End(3): ");
  396. scanf("%d", &position);
  397. FLUSH;
  398. if ( position < 1 || position > 3 )
  399. printf("Incorrect option. Please try again.\n");
  400. }
  401. return position;
  402. } // insertHandler
  403.  
  404. NODE *deleteNode (NODE *pList, NODE *pPre, NODE *pCur)
  405. {
  406. // Statements
  407. if ( pPre == NULL )
  408. pList = pCur->link;
  409. else
  410. pPre->link = pCur->link;
  411. free ( pCur );
  412. return pList;
  413. } // deleteNode
  414.  
  415. NODE *deleteManager (NODE *pList)
  416. {
  417. // Local Declarations
  418. NODE *pPre = NULL;
  419. NODE *pCur;
  420. char target[3];
  421. // Statements
  422. printf("Please enter a key: ");
  423. scanf("%2s", target);
  424. FLUSH;
  425. if ( searchList ( pList, &pPre, &pCur, target ) )
  426. pList = deleteNode ( pList, pPre, pCur );
  427. else
  428. printf("Country could not be found. Please try again.");
  429. return pList;
  430. } // deleteManager
  431.  
  432. NODE *destroyList (NODE *pList)
  433. {
  434. // Local Declarations
  435. NODE *pPre = NULL;
  436. NODE *pCur;
  437.  
  438. // Statements
  439. while ( pList ) {
  440. pCur = pList;
  441. free ( pCur->data.list.name );
  442. free ( pCur->data.list.capital );
  443. pList = deleteNode ( pList, pPre, pCur );
  444. }
  445. return pList;
  446. } // destroyList

Input file:
  1. HU Hungary; Budapest; 10006835
  2. MX Mexico; Mexico; 106202903
  3. CN China; Beijing; 1306313812
  4. NP Nepal; Kathmandu; 27676547
  5. MU Mauritius; Port Louis; 1230602
  6. FR France; Paris; 60656178
  7. ES Spain; Madrid; 40341462
  8. EG Egypt; Cairo; 77505756
  9. TW Taiwan; Taipei; 22894384
  10. GR Greece; Athens; 10668354
  11. US United States; Washington, DC; 295734134
  12. AU Australia; Canberra; 20090437
  13. LI Liechtenstein; Vaduz; 33717
  14. RU Russia; Moscow; 143420309
  15. CA Canada; Ottawa; 32805041
  16. MC Monaco; Monaco; 32409
  17. BR Brazil; Brasilia; 186112794
  18. IR Iran; Tehran; 68017860
  19. FR France; Paris; 60656178
  20. DO Dominican Republic; Santo Domingo; 8950034
  21. FJ Figi; Suva; 893354
Reply With Quote Quick reply to this message  
Join Date: Sep 2007
Posts: 16
Reputation: RaDeuX is an unknown quantity at this point 
Solved Threads: 0
RaDeuX RaDeuX is offline Offline
Newbie Poster

Re: Please help! Unknown memory leak with linked list nodes...

 
0
  #2
Dec 7th, 2008
Part of the issue was that I didn't give processListManager a return variable in main. Fixing it to
  1. list = processListManager(list);
so that's that. I'm still trying to see why I'm leaking though. Perhaps I'm overwriting my stack with scanf?
Reply With Quote Quick reply to this message  
Join Date: Dec 2005
Posts: 5,850
Reputation: Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute 
Solved Threads: 751
Team Colleague
Salem's Avatar
Salem Salem is offline Offline
Void main'ers are DOOMed

Re: Please help! Unknown memory leak with linked list nodes...

 
0
  #3
Dec 7th, 2008
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Other Threads in the C Forum


Views: 637 | Replies: 2
Thread Tools Search this Thread



Tag cloud for C
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC