Thread: Memory Leak?

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    3

    Memory Leak?

    hi guys,

    i need to do up a code to read a very big file 16M and also long line of like 32,000 characters and check for palindrome.
    the code i came up with eat up 23M of memory in solaris5.
    is there a memory leak somewhere?

    Code:
    /*
     *	Author:		Chua Jie Sheng
     *	Status:		read, output, checking pali not done
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    // definition
    /*
     * the higher the DEBUG_LEVEL, the more debug message to print
     * general guideline
     * 0 - no debug message
     * 1 - debug message
     * 2 - info 
     */
    
    //#define DEBUG_LEVEL 0
    #define ARRAY_SIZE (10000)
    
    // data structure
    
    struct linked_list {
    	char **text;
    	int size;
    	//int mismatch;
    };
    
    typedef struct linked_list list;
    
    list *current;
    //list *longest;
    //list *shortest;
    
    //char debug_buffer[50];
    int r, c;
    // prof protype
    void my_memusage(char *);
    
    // prototype
    //void debug(int lvl, char msg[]);
    int row(int index);
    int col(int index);
    list *create_list();
    char *realloc_list(char *to_be_realloc, int size);
    char check_char(int c);
    void put2char(int c);
    int char_matcher(int index, int size, char** text);
    void print_string();
    
    // developer methods
    /*
    void debug(int lvl, char msg[]) {
    	if (lvl <= DEBUG_LEVEL) {
    		printf("%s", msg);
    	}
    }
    */
    
    // data struc method
    int row(int index) {
    	r = (index - (index % ARRAY_SIZE)) / ARRAY_SIZE;
    	return r;
    }
    
    int col(int index) { 
    	c = index - (row(index)	 * ARRAY_SIZE);
    	return c;
    }
    
    // create new linked_list node
    list *create_list() {
    	list *created = (struct linked_list *)calloc(1, sizeof(list));
    	if (created == NULL) {
    		// debug
    		/*	
    		sprintf(debug_buffer, "unable to allocate memory.\n");
    		debug(1, debug_buffer);
    		*/
    		exit(1);
    	} else {
    		//created->text = (char **)malloc(1);
    		//created->text[0] = (char *)malloc(ARRAY_SIZE * sizeof(char));
    		created->size = 0;
    		//created->mismatch = 0;
    		return created;
    	}
    }
    
    // realloc memory to save space
    char *realloc_list(char *to_be_realloc, int size) {
    	return (char *)realloc(to_be_realloc, size);
    }
    
    // check char
    char check_char(int c) {
    	if (c > 31 && c < 127) {
    		return (char) c;
    	}
    	return NULL;
    }
    
    // handle adding of new char array
    void put2char(int c) {
    
    	// debug
    	/*	
    	sprintf(debug_buffer, "c = %d; ", c);
    	debug(2, debug_buffer);
    	//printf("%d ", c);
    	*/
    
    	// when current == null or c == 10
    	// go to next linked list when is a newline
    	if (c == 10 && current->size > 0) {
    
    		// debug	
    		/*
    		sprintf(debug_buffer, " -going next node.-\n");
    		debug(2, debug_buffer);
    		//printf(" -going next node.-\n");
    		*/
    
    		// check pali
    		int mismatch 
    			= char_matcher(0, current->size, current->text);
    		
    		/*
    		sprintf(debug_buffer, "mismatch: %d\n", mismatch);	
    		debug(1, debug_buffer);
    		*/
    
    		//
    		// print
    		if (mismatch == 0) {
    			// there is no error
    			// mismatch = 0
    			print_string(current);
    		}
    	
    		/*
    		sprintf(debug_buffer, "current->size: %d\n", current->size);
    		debug(1, debug_buffer);
    		*/
    
    		//
    		// discard
    		int index = 0;
    		for (; 
    			index < current->size; 
    			index=index+ARRAY_SIZE) {
    			free(current->text[row(index)]);
    		}
    		free(current->text);
    		free(current);
    
    		// create new list
    		current = create_list();
    		
    	}
    
    	char ch = check_char(c);
    	if (ch != NULL) {
    		
    		// debug
    		/*
    		sprintf(debug_buffer, "at %d, ch = %c\n", current->size, ch);
    		debug(1, debug_buffer);
    		*/
    
    		// is full
    		if ((current->size - (row(current->size) * ARRAY_SIZE )) == 0) {
    			// debug
    			/*
    			sprintf(debug_buffer, "at %d, creating next row.\n", current->size);
    			debug(1, debug_buffer);
    			*/
    
    			// create next row
    			current->text = 
    				(char **)realloc(current->text, row(current->size)+1);
    			
    			if (current->text) {
    				
    			}
    			
    			current->text[(row(current->size))] = 
    				(char *)malloc(ARRAY_SIZE * sizeof(char));
    		}
    		// move next
    		current->text[row(current->size)][col(current->size)] = ch;
    
    		current->size++;
    
    	} else {
    		// debug
    		/*	
    		sprintf(debug_buffer, "ch skipped.\n");
    		debug(1, debug_buffer);
    		//printf("ch = %c\n", ch);
    		*/
    	}
    
    }
    
    // char matcher for text
    int char_matcher(int index, int size, char** text) {
    	// return when reach middle
    	if (index == size/2) {
    		return 0;
    	}
    
    	// checking
    	// return 0 if no mismatch
    	// return 1 if there is mismatch
    	
    	int back = size-index-1;
    
    	if (text[row(index)][col(index)] == text[row(back)][col(back)]) {
    		return char_matcher(index+1, size, text);
    	} else {
    		return 1;
    	}	
    }
    
    
    // print string
    void print_string(list *list) {
    	int index = 0;
    
    	// loop the linked list
    	for (; 
    			index < list->size; 
    			index=index+ARRAY_SIZE) {
    		// printing only if there is text and is pali
    		int col = index % ARRAY_SIZE;
    		int row = index / ARRAY_SIZE;
    		printf("%s", list->text[row]);
    	}
    	printf("\n");
    }
    
    // only main method after this
    int main()
    {
    	// prof command
    	my_memusage("INIT");
    
    	int c; // note that c is int and not char
    
    	current = create_list();
    
    	while ((c = getchar()) != EOF) { // exit when EOF
    		put2char(c); /* copy input char to output */
    	}
    
    	my_memusage("END");
    	
    	// malloc space
    	print_process_memorysize();
    
    	return(0);
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    What are my_memusage() and print_process_memorysize() ?
    They're not standard functions, and you don't define them.

    As for the amount of memory you're using, look at your struct.
    It isn't just characters, there are int and lots of pointers to be stored as well.

    Also (depending on what you're actually measuring), realloc will fragment memory, so the actual amount in use by your program may be less than the amount allocated by the OS to your program.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    3
    my_memusage() and print_process_memorysize()
    is external file that are appointed by my prof so as to do memory calculation.

    is that when i realloc in this case, the data that is copied is just pointer which is lesser if i were to copy a whole chunk of 32k char isn't?

    measurement was done via "ps" program.
    another thing to add is that the time need for my program to process the 32k file is 2min far longer then my other friends average of 9sec.
    (even when i comment off all debugging code, the run time is still around there.)

    my friend utilize a single-d array and realloc as they needed more memory.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Ok, think about this... You're looking for palindromes ... words that are spelled the same forward and backward...

    Are you making any other use of that file in your program?

    If your answer is "no"...
    Exactly how many words from that file does your program need to be aware of at any one time, in order to do it's job?

  5. #5
    Registered User
    Join Date
    Mar 2011
    Posts
    3
    no, the file is not of use in the program.

    the input is of variable length. so quite not possible to read half i guess.

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by lovercjs View Post
    no, the file is not of use in the program.

    the input is of variable length. so quite not possible to read half i guess.
    Nope... to find a palendromic word you only need to be aware of 1 word at a time...

    1) Read 1 word from the file
    2) test it for palindrome status
    3) If it is a palindrome display it, count it or store it
    5) while not at end of file goto step 1

    It's a simple loop... There is no reason at all to have the entire file in memory to accomplish your task. Moerover, if you do go word by word, the file can be any size and can contain any number of words and your maximum memory usage will be for 1 word, not the entire file.

    Take a look in your docs and see what fscanf("%s",word) does...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory leak in this case?
    By George2 in forum C++ Programming
    Replies: 3
    Last Post: 03-22-2008, 05:05 AM
  2. memory leak in the code?
    By George2 in forum C++ Programming
    Replies: 20
    Last Post: 01-13-2008, 06:50 AM
  3. Is this code memory leak free? ---> POSIX Threads
    By avalanche333 in forum C++ Programming
    Replies: 9
    Last Post: 04-13-2007, 03:19 PM
  4. Any Memory Leak Checking Tool?
    By George2 in forum C Programming
    Replies: 4
    Last Post: 06-21-2006, 11:02 PM
  5. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM

Tags for this Thread