Thread: Memory leaks problem in C -- Help please

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    5

    Memory leaks problem in C -- Help please

    Hi !

    I'm quite new to C-programming. I am working on a program to make operations on polynoms. My problem is that I have memory leaks (I checked with valgrind) but I don't know where and how to get rid of these! (I don't really understand the valgrind output...)

    I would be pleased that someone can help me, I'm sure it is not really complicated but I'm really stuck on this...

    Thank you very much in advance

    Here is the Valgrind output:
    Code:
    ==16436== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1)
    ==16436== malloc/free: in use at exit: 45,134 bytes in 1,301 blocks.
    ==16436== malloc/free: 5,015 allocs, 3,714 frees, 177,109 bytes allocated.
    ==16436== For counts of detected errors, rerun with: -v
    ==16436== searching for pointers to 1,301 not-freed blocks.
    ==16436== checked 130,212 bytes.
    ==16436== 
    ==16436== 12 bytes in 1 blocks are still reachable in loss record 1 of 5
    ==16436==    at 0x4022862: realloc (vg_replace_malloc.c:306)
    ==16436==    by 0x80594E1: (within /usr/bin/make)
    ==16436==    by 0x804B04A: (within /usr/bin/make)
    ==16436==    by 0x805FE7A: (within /usr/bin/make)
    ==16436==    by 0x8060DDA: (within /usr/bin/make)
    ==16436==    by 0x8058B0F: (within /usr/bin/make)
    ==16436==    by 0x405004F: (below main) (in /lib/tls/i686/cmov/libc-2.6.1.so)
    ==16436== 
    ==16436== 
    ==16436== 46 bytes in 3 blocks are still reachable in loss record 2 of 5
    ==16436==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==16436==    by 0x80594F4: (within /usr/bin/make)
    ==16436==    by 0x804B71A: (within /usr/bin/make)
    ==16436==    by 0x804B97D: (within /usr/bin/make)
    ==16436==    by 0x8060110: (within /usr/bin/make)
    ==16436==    by 0x8060DDA: (within /usr/bin/make)
    ==16436==    by 0x8058B0F: (within /usr/bin/make)
    ==16436==    by 0x405004F: (below main) (in /lib/tls/i686/cmov/libc-2.6.1.so)
    ==16436== 
    ==16436== 
    ==16436== 4,234 bytes in 212 blocks are still reachable in loss record 3 of 5
    ==16436==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==16436==    by 0x40AA2CF: strdup (in /lib/tls/i686/cmov/libc-2.6.1.so)
    ==16436==    by 0x8059480: (within /usr/bin/make)
    ==16436==    by 0x805762A: (within /usr/bin/make)
    ==16436==    by 0x405004F: (below main) (in /lib/tls/i686/cmov/libc-2.6.1.so)
    ==16436== 
    ==16436== 
    ==16436== 16,384 bytes in 15 blocks are still reachable in loss record 4 of 5
    ==16436==    at 0x4021AA4: calloc (vg_replace_malloc.c:279)
    ==16436==    by 0x80653B7: (within /usr/bin/make)
    ==16436==    by 0x8062C11: (within /usr/bin/make)
    ==16436==    by 0x80575E8: (within /usr/bin/make)
    ==16436==    by 0x405004F: (below main) (in /lib/tls/i686/cmov/libc-2.6.1.so)
    ==16436== 
    ==16436== 
    ==16436== 24,458 bytes in 1,070 blocks are still reachable in loss record 5 of 5
    ==16436==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==16436==    by 0x8059546: (within /usr/bin/make)
    ==16436==    by 0x80636BB: (within /usr/bin/make)
    ==16436==    by 0x805766F: (within /usr/bin/make)
    ==16436==    by 0x405004F: (below main) (in /lib/tls/i686/cmov/libc-2.6.1.so)
    ==16436== 
    ==16436== LEAK SUMMARY:
    ==16436==    definitely lost: 0 bytes in 0 blocks.
    ==16436==      possibly lost: 0 bytes in 0 blocks.
    ==16436==    still reachable: 45,134 bytes in 1,301 blocks.
    ==16436==         suppressed: 0 bytes in 0 blocks.
    Here is my code (quite long, but not really complicated):

    Code:
    #include <stdbool.h>
    
    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <ctype.h>
    
    #include <math.h>
    #include <string.h>
    
    
    
    #include "error.h"
    
    #include "poly.h"
    
    
    
    /*MACROS*/
    
    #define PAUSE { {printf("\nPress 'Enter' to quit...\n"); while(getchar() != '\n'){;}} }
    
    
    
    #define EMALLOC(type,v,N) { if( (v = (type*)  malloc(N*sizeof(type))) == NULL){\
    
    error("ERROR: malloc failed, out of memory");}; }
    
    
    
    #define EREALLOC(type,v,N) { type* temp = NULL; \
    
    if ((temp = (type*) realloc(v, N*sizeof(type))) == NULL){\
    
    error("ERROR: realloc failed, out of memory");}; v = temp; free(&temp); }
    
    
    
    #define PASS_NEXT(tmp,var,copy)\
    
    { tmp = var; var = poly_copy(copy); tmp->prev = var; var->next = tmp; }
    
    
    
    
    
    /*STRUCTURE DECLARATION*/
    
    typedef struct poly_t *pointer;
    
    
    
    typedef struct poly_t{
    
    	pointer prev;	//Points the prev element of the list 
    
    	long coeff;
    
            long exponent;
    
            pointer next;	//Points the next element of the list (Double-linked list)
    
            }poly;
    
    
    
    /*PROTOTYPE FUNCTIONS*/
    
    poly_t* string_to_struct(const char*);	//takes a part of the string and save it as a poly structure
    
    char* 	short_string(const char*,int);	//makes the string shorter (ignoring spaces before and after)
    
    char* 	next_element(const char* string); //returns the next element of the string 
    
    poly_t* poly_copy(poly_t*);	//copies one element of the list of polynoms
    
    poly_t* poly_copy_all(poly_t*);	//copies all the element of the list of polynoms
    
    poly_t* max_deg	(poly_t*);	//returns the element with the higher exponent
    
    
    
    	
    
    /*FUNCTION NEW POLY*/
    
    
    
    poly_t* new_poly_from_string(const char* string)
    
    {
    
    	poly_t *new = NULL;
    
    	poly_t *tmp = NULL;
    
    	char* s;
    	EMALLOC(char,s,strlen(string)+1);
    	
    
    		s = strcpy(s,string);
    
    		char* poly_el;
    
    		while(strlen(s) > 0)
    
    		{
    
    			poly_el = next_element(s);
    
    			if(new == NULL)
    
    				new = string_to_struct(poly_el);
    
    			else
    
    			{
    
    				tmp = new;
    
    				new = string_to_struct(poly_el);
    
    				tmp->next = new;
    
    				new->prev = tmp;
    
    			}
    
    			s = short_string(s,strlen(poly_el));
    
    		}
    		free(poly_el);
    
    
    	free(s);
    	free_poly(tmp);
    
    	return new;	
    
    }
    
    
    
    /*FUNCTION ADD*/
    
    
    
    poly_t* add(poly_t* poly1, poly_t* poly2)
    
    {
    
    	poly_t *add_poly = NULL;
    
    	poly_t *tmp = NULL;
    
    	
    
    	poly_t *poly1_copy = poly_copy_all(poly1);
    
    	poly_t *poly2_copy = poly_copy_all(poly2);
    
    	
    
    	//Handle extrem cases
    
    	if(poly1==NULL)
    
    		return poly2_copy;
    
    	else if(poly2==NULL)
    
    		return poly1_copy;
    
    	else if( (poly1 == NULL)&&(poly2 == NULL) )
    
    		return NULL;
    
    
    
    	
    
    	//Algorithm
    
    	poly_t *max1 = max_deg(poly1_copy);
    
    	poly_t *max2 = max_deg(poly2_copy);
    
    	
    
    	while( (max1->exponent != -1)||(max2->exponent != -1) )
    
    	{	
    
    		if(max1->exponent > max2->exponent)
    
    		{
    
    			if(add_poly == NULL)
    
    				add_poly = poly_copy(max1);
    
    			else
    
    				PASS_NEXT(tmp,add_poly,max1)
    
    			
    
    			max1->exponent = -1;
    
    		}
    
    		else if(max2->exponent > max1->exponent)
    
    		{
    
    			if(add_poly == NULL)
    
    				add_poly = poly_copy(max2);
    
    			else
    
    				PASS_NEXT(tmp,add_poly,max2)
    
    			
    
    			max2->exponent = -1;
    
    		}
    
    		else
    
    		{
    
    			if(add_poly == NULL)
    
    				add_poly = poly_copy(max2);
    
    			else
    
    				PASS_NEXT(tmp,add_poly,max2)
    
    			
    
    			add_poly->coeff += max1->coeff;
    
    			max1->exponent = -1;
    
    			max2->exponent = -1;
    
    		}
    
    		
    
    		max1 = max_deg(poly1_copy);
    
    		max2 = max_deg(poly2_copy);
    
    	}
    
    	
    
    	free_poly(poly1_copy);
    
    	free_poly(poly2_copy);
    
    	
    
    	while(add_poly->next!=NULL)
    
    		add_poly = add_poly->next;
    
    	
    
    	return add_poly;
    
    }
    
    
    
    /*FUNCTION MUL*/
    
    
    
    poly_t* mul(poly_t* poly1, poly_t* poly2){
    
    	poly_t* mul_poly = NULL;
    
    	
    
    	poly_t *poly1_copy = poly_copy_all(poly1);
    
    	
    
    	while(poly1_copy != NULL)
    
    	{
    
    		poly_t *poly2_copy = poly_copy_all(poly2);
    
    		
    
    		while(poly2_copy != NULL)
    
    		{
    
    			poly_t *tmp = poly_copy(poly1_copy);
    
    			tmp->exponent += poly2_copy->exponent;
    
    			tmp->coeff *= poly2_copy->coeff;
    
    			
    
    			mul_poly = add(mul_poly,tmp);
    
    			
    
    			free(tmp);
    
    			
    
    			if(poly2_copy->prev == NULL)
    
    			{
    
    				poly_t *trash;
    
    				trash = poly2_copy;
    
    				poly2_copy = NULL;
    
    				free_poly(trash);
    
    			}
    
    			else
    
    				poly2_copy = poly2_copy->prev;
    
    		}
    
    		
    
    		if(poly1_copy->prev == NULL)
    
    		{
    
    			poly_t *trash;
    
    			trash = poly1_copy;
    
    			poly1_copy = NULL;
    
    			free_poly(trash);
    
    		}
    
    		else
    
    			poly1_copy = poly1_copy->prev;
    
    	free_poly(poly2_copy);
    	}
    
    	free_poly(poly1_copy);
    
    	return mul_poly;
    
    }
    
    
    
    /*FUNCTION FREE_POLY*/
    
    
    
    void free_poly(poly_t* poly){
    
    	poly_t* p = poly;
    
    	poly_t* q;
    
    	
    
    	if(p->next == NULL){
    
    		while(p !=NULL){
    
    			q = p->prev;
    
    			free(p);
    
    			p = q;
    
    		}
    
    	}
    
    	
    
    	else{
    
    		while(p !=NULL){
    
    			q = p->next;
    
    			free(p);
    
    			p = q;
    
    		}
    
    	}
    	free(q);
    
    }
    
    
    
    /*FUNCTION PRINT_POLY*/
    
    
    
    void print_poly(poly_t* poly)
    
    {
    
    	poly_t *temp = poly;
    
    	
    
    	if(temp == NULL)
    
    	{
    
    		printf("Null polynomial\n"); 
    
    		return;
    
    	}
    
    	
    
    	while (temp != NULL)
    
    	{
    
    		if(temp->coeff == 0)
    
    			continue;
    
    		
    
    		if(temp->coeff < 0)
    
    			printf("- ");
    
    		
    
    		if( ((temp->next!=NULL)&&(temp->coeff > 0))||(temp->prev==NULL) )
    
    			printf("+ ");
    
    		
    
    		if( (abs(temp->coeff) > 1)||((abs(temp->coeff)==1)&&(temp->exponent == 0)))
    
    			printf("%d ",abs(temp->coeff));
    
    		
    
    		if(temp->exponent == 1)
    
    			printf("x ");
    
    		else if(temp->exponent > 1)
    
    			printf("x^%ld ",temp->exponent);
    
    		else
    
    			printf(" ");
    
    
    
    	temp = temp->prev; 
    
    	}
    
    	printf("\n");
    	free_poly(temp);
    
    }
    
    
    
    /*OTHER FUNCTIONS*/
    
    
    
    poly_t* string_to_struct(const char *poly_el_string)
    
    {
    
    	poly_t * poly_el_struct = NULL;
    
    	if(strlen(poly_el_string) <= 1)
    
    		return poly_el_struct;
    
    	
    
    	EMALLOC(poly_t,poly_el_struct,1);
    
    	poly_el_struct->prev = NULL;
    
    	poly_el_struct->next = NULL;
    
    	
    
    	char c;
    
    	int i = 0;
    
    	int rank = 0;
    
    
    
    	if(isdigit(c = poly_el_string[i]))
    
    	{
    
    		double buff = 0;
    
    		while((i < strlen(poly_el_string))&&(isdigit(c = poly_el_string[i++])))
    
    			buff += (c-'0')*pow(10,rank++);
    
    		
    
    		if( (i < strlen(poly_el_string))&&(c == '^') )
    
    		{
    
    			poly_el_struct->exponent = buff;
    
    			i++;
    
    			rank = 0;
    
    			if(!isdigit(c = poly_el_string[i]))
    
    				poly_el_struct->coeff = 1;
    
    			else
    
    				poly_el_struct->coeff = 0;
    
    			
    
    			while((i < strlen(poly_el_string))&&(isdigit(c = poly_el_string[i++])))
    
    				poly_el_struct->coeff += (long)(c-'0')*pow(10,rank++);	
    
    			
    
    			if((i < strlen(poly_el_string))&&(c == '-'))
    
    				poly_el_struct->coeff = - poly_el_struct->coeff;
    
    		}
    
    		else
    
    		{
    
    			poly_el_struct->coeff = buff;
    
    			poly_el_struct->exponent = 0;
    
    		}
    		free(&buff);
    
    	}
    
    	else
    
    	{
    
    		i++;
    
    		poly_el_struct->coeff = 0;
    
    		while((i < strlen(poly_el_string))&&(isdigit(c = poly_el_string[i++])))
    
    			poly_el_struct->coeff += (long) (c-'0')*pow(10,rank++);
    
    		
    
    		if(c == '-')
    
    			poly_el_struct->coeff *= -1;
    
    
    
    		poly_el_struct->exponent = 1;
    
    	}
    	free(&c);
    	free(&i);
    	free(&rank);
    
    	return poly_el_struct;
    
    }
    
    
    
    char* next_element(const char* string){
    
    	int i = strlen(string)-1;
    
    	char c;
    
    	
    
    	char *el;
    
    	//EMALLOC(char,el,1);
    	el = malloc(sizeof(char)+1);
    	if(el==NULL)
    		printf("ERROR : out of memory. \nmalloc failed");
    
    	
    	int j = 0;
    
    	
    
    	while(i > -1)
    
    	{
    
    		c = string[i--];
    
    		
    
    		if(isspace(c))
    
    			continue;
    
    		
    
    		el[j] = c;
    
    		EREALLOC(char,el,++j);
    
    		
    
    		if( (c == '+')||(c == '-') )
    
    			break;
    
    	}
    
    	*(el+j) = '\0';
    	free(&c);
    	free(&i);
    
    	return el;
    
    }
    
    
    
    char* short_string(const char *s_old, int l){
    
    	char *s_new = NULL;
    
    	
    
    	int spaces = 0;
    
    	
    
    	if( (strlen(s_old) != l) )
    
    	{
    
    		if(strlen(s_old) != l+1)
    
    			spaces = 2;
    
    		else
    
    			spaces = 1;
    
    	}
    
    
    
    	int new_l = strlen(s_old)-l-spaces ;
    
    	
    
    	//EMALLOC(char,s_new,new_l)
    	s_new = malloc(new_l*sizeof(char));
    	if(s_new==NULL)
    		printf("ERROR : out of memory. \nmalloc failed");
    
    	strncpy(s_new,s_old,new_l);
    
    	s_new[new_l] = '\0';
    
    	free(&spaces);
    	free(&new_l);
    
    	return s_new;
    
    }
    
    
    
    poly_t* max_deg(poly_t *poly){
    
    	poly_t *max = poly;
    
    
    
    	while( (poly != NULL)&&(poly->prev != NULL) )
    
    	{
    
    		if(poly->exponent < (poly->prev)->exponent)
    
    			max = poly->prev;
    
    		
    
    		poly = poly->prev;
    
    	}
    
    	return max;
    
    }
    
    
    
    poly_t* poly_copy_all(poly_t *poly){
    
    	poly_t *copy = NULL;
    
    	poly_t *tmp = NULL;
    
    	
    
    	if(poly == NULL)
    
    		return NULL;
    
    	
    
    	if(poly->next == NULL)
    
    	{
    
    		while(poly != NULL)
    
    		{
    
    			if(copy == NULL)
    
    				copy = poly_copy(poly);
    
    			else
    
    			{
    
    				tmp = copy;
    
    				copy = poly_copy(poly);
    
    				tmp->prev = copy;
    
    				copy->next = tmp;
    
    			}
    
    			
    
    			poly = poly->prev;
    
    		}
    
    		
    
    		while(copy->next != NULL)
    
    			copy = copy->next;
    
    	}
    
    	else
    
    	{
    
    		while(poly != NULL)
    
    		{
    
    			if(copy == NULL)
    
    				copy = poly_copy(poly);
    
    			else
    
    			{
    
    			tmp = copy;
    
    			copy = poly_copy(poly);
    
    			tmp->next = copy;
    
    			copy->prev = tmp;
    
    			}
    
    			
    
    			poly = poly->prev;
    
    		}
    
    		
    
    		while(copy->prev != NULL)
    
    			copy = copy->prev;
    
    	}
    	free_poly(tmp);
    
    	return copy;
    
    }
    
    
    
    poly_t* poly_copy(poly_t *poly){	
    
    	poly_t *cpy;
    
    	//EMALLOC(poly_t,cpy,1);
    
    	cpy = malloc(sizeof(poly_t));	
    	if(cpy==NULL)
    		printf("ERROR : out of memory. \nmalloc failed");
    	else{	
    
    	cpy->coeff = poly->coeff;
    
    	cpy->exponent = poly->exponent;
    
    	
    
    	cpy->next = NULL;
    
    	cpy->prev = NULL;
    	}
    
    	return cpy;
    
    }

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    To me, your valgrind results appear to relate to /usr/bin/make, rather than your application. What command are you giving when you use valgrind?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    May 2008
    Posts
    5
    Hi

    I use this command (but i'm not sure that is a right way to do...):
    valgrind --tool=memcheck --leak-check=full --show-reachable=yes make

    (I'm new to Linux, Valgrind, and C, that is why I maybe make complete newbie mistakes!)

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    That, to me, would run "make" under valgrind conditions. Would it not be better to run your application in valgrind?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    May 2008
    Posts
    5
    I think i understand what you mean but I don't know how to do... How to run an application in valgrind ? Isn't it the same as running under valgrind conditions ?

    Do someone find something wrong (memory leaks) in my code?

    Thanks for helping!

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Your code is complex enough that it's not trivial to see if it's got memory leaks or not.

    To run valgrind on your program, you do something like this:
    Code:
    valgrind --tool=memcheck --leak-check=full --show-reachable=yes myprog
    You may have to add more arguments to your program. I can't find main in your code, so I'm not sure what arguments it may require.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    May 2008
    Posts
    5
    Ok, now i run in valgrind and I have more understandable output I think.
    I'll try to fix this, and if maybe i'll post again if can't fix the memory leaks !

    Thank you very much!

    If people want to take a look, here is the output of Valgrind:

    Code:
    Begin polynomial test of (x^2 - 7x + 1) * (3x + 2)
    ==27963== Invalid free() / delete / delete[]
    ==27963==    at 0x402237F: free (vg_replace_malloc.c:233)
    ==27963==    by 0x804939C: next_element (poly.c:344)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0xBED5C600 is on thread 1's stack
    ==27963== 
    ==27963== Invalid write of size 1
    ==27963==    at 0x804933F: next_element (poly.c:343)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0x41A1069 is 0 bytes after a block of size 1 alloc'd
    ==27963==    at 0x4022862: realloc (vg_replace_malloc.c:306)
    ==27963==    by 0x804935D: next_element (poly.c:344)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid write of size 1
    ==27963==    at 0x80493BF: next_element (poly.c:349)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0x41A10A2 is 0 bytes after a block of size 2 alloc'd
    ==27963==    at 0x4022862: realloc (vg_replace_malloc.c:306)
    ==27963==    by 0x804935D: next_element (poly.c:344)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid free() / delete / delete[]
    ==27963==    at 0x402237F: free (vg_replace_malloc.c:233)
    ==27963==    by 0x80493CC: next_element (poly.c:350)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0xBED5C613 is on thread 1's stack
    ==27963== 
    ==27963== Invalid free() / delete / delete[]
    ==27963==    at 0x402237F: free (vg_replace_malloc.c:233)
    ==27963==    by 0x80493D7: next_element (poly.c:351)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0xBED5C604 is on thread 1's stack
    ==27963== 
    ==27963== Conditional jump or move depends on uninitialised value(s)
    ==27963==    at 0x8048E16: string_to_struct (poly.c:266)
    ==27963==    by 0x80488A3: new_poly_from_string (poly.c:66)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Conditional jump or move depends on uninitialised value(s)
    ==27963==    at 0x80488E2: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid write of size 1
    ==27963==    at 0x80494BE: short_string (poly.c:375)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0x41A10E1 is 0 bytes after a block of size 9 alloc'd
    ==27963==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==27963==    by 0x8049489: short_string (poly.c:371)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid free() / delete / delete[]
    ==27963==    at 0x402237F: free (vg_replace_malloc.c:233)
    ==27963==    by 0x80494CB: short_string (poly.c:377)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0xBED5C60C is on thread 1's stack
    ==27963== 
    ==27963== Invalid free() / delete / delete[]
    ==27963==    at 0x402237F: free (vg_replace_malloc.c:233)
    ==27963==    by 0x80494D6: short_string (poly.c:378)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0xBED5C608 is on thread 1's stack
    ==27963== 
    ==27963== Invalid read of size 1
    ==27963==    at 0x80492C1: next_element (poly.c:325)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0x41A10E1 is 0 bytes after a block of size 9 alloc'd
    ==27963==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==27963==    by 0x8049489: short_string (poly.c:371)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid read of size 1
    ==27963==    at 0x804940A: short_string (poly.c:360)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0x41A10E1 is 0 bytes after a block of size 9 alloc'd
    ==27963==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==27963==    by 0x8049489: short_string (poly.c:371)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid read of size 1
    ==27963==    at 0x804942E: short_string (poly.c:362)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0x41A10E1 is 0 bytes after a block of size 9 alloc'd
    ==27963==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==27963==    by 0x8049489: short_string (poly.c:371)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid read of size 1
    ==27963==    at 0x8049465: short_string (poly.c:368)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0x41A10E1 is 0 bytes after a block of size 9 alloc'd
    ==27963==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==27963==    by 0x8049489: short_string (poly.c:371)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid read of size 1
    ==27963==    at 0x8048E16: string_to_struct (poly.c:266)
    ==27963==    by 0x80488A3: new_poly_from_string (poly.c:66)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0x41A11F9 is 0 bytes after a block of size 1 alloc'd
    ==27963==    at 0x4022862: realloc (vg_replace_malloc.c:306)
    ==27963==    by 0x804935D: next_element (poly.c:344)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid read of size 1
    ==27963==    at 0x80488E2: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0x41A11F9 is 0 bytes after a block of size 1 alloc'd
    ==27963==    at 0x4022862: realloc (vg_replace_malloc.c:306)
    ==27963==    by 0x804935D: next_element (poly.c:344)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid read of size 1
    ==27963==    at 0x8048900: new_poly_from_string (poly.c:62)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0x41A1310 is 0 bytes after a block of size 0 alloc'd
    ==27963==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==27963==    by 0x8049489: short_string (poly.c:371)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== Invalid read of size 4
    ==27963==    at 0x8048C62: free_poly (poly.c:204)
    ==27963==    by 0x804892B: new_poly_from_string (poly.c:79)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963==  Address 0xC is not stack'd, malloc'd or (recently) free'd
    ==27963== 
    ==27963== Process terminating with default action of signal 11 (SIGSEGV)
    ==27963==  Access not within mapped region at address 0xC
    ==27963==    at 0x8048C62: free_poly (poly.c:204)
    ==27963==    by 0x804892B: new_poly_from_string (poly.c:79)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== ERROR SUMMARY: 60 errors from 18 contexts (suppressed: 13 from 1)
    ==27963== malloc/free: in use at exit: 37 bytes in 7 blocks.
    ==27963== malloc/free: 18 allocs, 36 frees, 55 bytes allocated.
    ==27963== For counts of detected errors, rerun with: -v
    ==27963== searching for pointers to 7 not-freed blocks.
    ==27963== checked 68,012 bytes.
    ==27963== 
    ==27963== 
    ==27963== 6 bytes in 3 blocks are definitely lost in loss record 1 of 3
    ==27963==    at 0x4022862: realloc (vg_replace_malloc.c:306)
    ==27963==    by 0x804935D: next_element (poly.c:344)
    ==27963==    by 0x804888F: new_poly_from_string (poly.c:64)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== 
    ==27963== 13 bytes in 1 blocks are definitely lost in loss record 2 of 3
    ==27963==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==27963==    by 0x8048840: new_poly_from_string (poly.c:58)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== 
    ==27963== 18 bytes in 3 blocks are definitely lost in loss record 3 of 3
    ==27963==    at 0x4022765: malloc (vg_replace_malloc.c:149)
    ==27963==    by 0x8049489: short_string (poly.c:371)
    ==27963==    by 0x80488F9: new_poly_from_string (poly.c:74)
    ==27963==    by 0x804872E: poly_test (main.c:18)
    ==27963==    by 0x80487E1: main (main.c:39)
    ==27963== 
    ==27963== LEAK SUMMARY:
    ==27963==    definitely lost: 37 bytes in 7 blocks.
    ==27963==      possibly lost: 0 bytes in 0 blocks.
    ==27963==    still reachable: 0 bytes in 0 blocks.
    ==27963==         suppressed: 0 bytes in 0 blocks.
    Erreur de segmentation (core dumped)

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    One strangeness in your code is that you are freeing local variables, e.g:
    Code:
    	char c;
    	int i = 0;
    	int rank = 0;
            ....
    	free(&c);
    	free(&i);
    	free(&rank);
    I believe free is only for deallocating memory that you have allocated dynamically. Local variables should be popped from the stack automatically.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by anon View Post
    One strangeness in your code is that you are freeing local variables, e.g:
    Code:
    	char c;
    	int i = 0;
    	int rank = 0;
            ....
    	free(&c);
    	free(&i);
    	free(&rank);
    I believe free is only for deallocating memory that you have allocated dynamically. Local variables should be popped from the stack automatically.
    Definitely, you should never free anything that didn't come from malloc, and never delete (in C++) anything that didn't come from new.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    May 2008
    Posts
    5
    Yes that's true I've just corrected that.

    The main problems are in the macros I think, or the way I use these in the code. I have lots of invalid read and/or write in the Valgrind ouptut, and each time I use the macro EMALLOC, or EREALLOC it creates loss of memory....However, it try to free what i've allocated...

    I probably miss something important ...

  11. #11
    The larch
    Join Date
    May 2006
    Posts
    3,573
    For example here:
    Code:
    	int new_l = strlen(s_old)-l-spaces ;	
    
    	//EMALLOC(char,s_new,new_l)
    	s_new = malloc(new_l*sizeof(char));
    	if(s_new==NULL)
    		printf("ERROR : out of memory. \nmalloc failed");
    
    	strncpy(s_new,s_old,new_l);
    	s_new[new_l] = '\0';
    The last line accesses array out of bounds.

    Your macros are somewhat broken because N is not in brackets.

    For example this usage:
    Code:
    EMALLOC(char,s,strlen(string)+1);
    gets converted into this:
    Code:
    { if( (s = (char*) malloc(strlen(string)+1*sizeof(char))) == NULL){error("ERROR: malloc failed, out of memory");}; };
    As you can see it is not strlen() + 1 times the size. Here you just get away with it because the size of char happens to be 1 always, so the multiplication wouldn't have any effect anyway.

    In EREALLOC you are again freeing a local variable:
    Code:
    #define EREALLOC(type,v,N) { type* temp = NULL; \
    if ((temp = (type*) realloc(v, N*sizeof(type))) == NULL){\
    error("ERROR: realloc failed, out of memory");}; v = temp; free(&temp); }
    There are probably more memory-related errors. I guess the biggest problem is not potential memory leaks but such errors.
    May-be you could post a runnable program and / or explain what all parts of it are doing.

    And by the way, are you really using that many blank lines? IMO, they don't really improve readability, they just hinder seeing a whole function on the screen at one time.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, I would also get rid of those macros (make it a function!), and take care of all warnings you get too. Free doesn't take a type** argument.
    Bump warnings up to max too while you're at it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Yes, I would also get rid of those macros (make it a function!), and take care of all warnings you get too. Free doesn't take a type** argument.
    Bump warnings up to max too while you're at it.
    I completely agree on the removal of the macros - using functions is MUCH better and easier to debug.

    Actually, with the risk of you saying "that's another reason why C is unsafe", you are wrong - free takes a void *, which means that any pointer is valid input from the language's perspective. That is just the way C is, ok?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Right, makes sense...
    Although it's still wrong, so that's something the OP could fix!
    Last edited by Elysia; 05-21-2008 at 11:43 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Right, makes sense...
    Although it's still wrong, so that something the OP could fix!
    Yes, of course!

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problem with data in allocated memory
    By supi in forum C Programming
    Replies: 3
    Last Post: 06-09-2008, 02:06 AM
  2. Pointer's
    By xlordt in forum C Programming
    Replies: 13
    Last Post: 10-14-2003, 02:15 PM
  3. Question about Memory Leaks with *char
    By Diamonds in forum C++ Programming
    Replies: 11
    Last Post: 12-16-2002, 07:00 AM
  4. Is it necessary to write a specific memory manager ?
    By Morglum in forum Game Programming
    Replies: 18
    Last Post: 07-01-2002, 01:41 PM
  5. Memory Problem - I think...
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 10-24-2001, 12:14 PM