Link to home
Start Free TrialLog in
Avatar of David Paris Vicente
David Paris VicenteFlag for Spain

asked on

Stuck when try to free pointer.

Hi.

I´m  new to C, and i´m stuck with this error.
When i try to free te pointer a heap error ocurred. I try to figured out, with no sucess.
Every thing is working fine if i don´t try to free the pointer at the end of the program, but i want to free the pointer.
Can someone help me  understand what i´m doing wrong.

In attachement goes my code

Thank you all
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#define MAX 100


float uniforme()//funçao que que gera valores entre 0 e 1
{
	float d;
	
	d = rand()%10000+1;
	d = d / 10000;
	return d;
}
char* memTamanho(char * buf, size_t NovoTam, size_t TamAntigo)
{
	void *newInput ; 
    newInput = realloc(buf, NovoTam);
	if (newInput == NULL)
	{
		printf("Erro a realocar a memoria.\n");
		return NULL ; 
	}
    return (char*)newInput;
}


/*Função que calcula os tempos de volta de cada Piloto*/
float tempos_volta(float *v_medios,int i)
{
	int n=0,k;
	float erros=0, prob_erro=0.5, val_aleatorio, tempo_volta=5.00, soma=0.0, aux=0.0, Mtempo[3]={'\0'};
	for(n;n<3;n++)
		{
			prob_erro=((prob_erro*i)/10);
			if(prob_erro>=0.5)
				prob_erro=0.5;
			else
				prob_erro;

			for(k=0; k<24;k++)
				{
					/*chama a função que vai gerar o valor entre 0 e 1*/
					val_aleatorio=uniforme();
					soma=soma+val_aleatorio;
				}	
			/*Condição que incrementa o numero de erros por volta*/
			val_aleatorio=uniforme();
			while(val_aleatorio<=prob_erro)
				{
					erros=erros+tempo_volta;
					val_aleatorio=uniforme();		
				}
			aux=(((soma/12)*v_medios[i-1])+erros);
			Mtempo[n]=aux;
			erros=0;
			soma=0;
		}	
	n=0;
	/*Condição que analisa o melhor tempo das 3 voltas*/
	while (n<2)
		{
			if(Mtempo[n]>Mtempo[n+1])
				aux=Mtempo[n+1];
			else
				aux=Mtempo[n];
			n++;
		}
	return aux;
}
/*Função que imprime a melhor volta das 3*/
void volta( float *v_medios, int i)
{
	float M_volta;
	int n=1;

	while(i>=1)
		{		
			M_volta=tempos_volta (v_medios, i);
			printf("%d. Piloto (%.2f): %.2f\n",n, v_medios[i-1], M_volta);
			i--;
			n++;
		}
}

/*Função que parte a string inserida, para dentro de um vector*/
void InsereVmedios(char *input_medios)
{
	float *v_medios;
	char *string;
	int i=0;

	v_medios=(float*) malloc(sizeof(float*)*i+1);
	string=(char*)strtok(input_medios," ");

	while(string!=NULL)
		{	
			v_medios[i]=atof(string);//muda o valor de char para float
			string=(char*)strtok(NULL," ");
			i++;		
		}
	volta(v_medios,i);
	
}


int main()
{
	char *input_medios, *buf, string;
	size_t tamMem = 1;
	size_t MemUsada = 0;

	srand(1);
 
	buf= (char*)malloc((tamMem)*sizeof(char));
	if(buf == NULL)
		{
			printf("Erro de memoria.\n");
			return -1;
		}
	input_medios=buf;
	printf("Indique tempos medios dos pilotos, separados por espacos:\n");
	while ((string = fgetc(stdin))!= '\n')
		{		
			*input_medios++=string;
			MemUsada++;
			if (tamMem==MemUsada)
				{
					MemUsada *= 2;
					buf= memTamanho(buf, tamMem, MemUsada);
					input_medios= buf + (MemUsada-1);
					if(buf== NULL)
						return -1;
				}
		}
	printf("\nQualificacao:\n\n");
	InsereVmedios(buf);
	//free(buf); problem here
	//buf=NULL;
	return 0;
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of David Paris Vicente

ASKER

Hi Infinity08

Thank you for your help.

I did like you said and work.

But i have another question if you don´t mind to explain.
As you can see in the function void InsereVmedios(char *input_medios)

 line 93: v_medios=(float*) malloc(sizeof(float*)*i+1);

I use again malloc to that pointer, so i have to free that pointer?(wright)
And i also have to free the input_medios variable?

I´m asking that because i try to free them but the some error appear.

But like i said maybe this are a newbie questions but i´m not confortable with C and less more with pointers and dynamic memory.

I´m very appreciated for your help.
Thanks again
>> I use again malloc to that pointer, so i have to free that pointer?(wright)

Right.

Basically, it comes down to this : for every allocation you do, you need a corresponding free. Since you call malloc inside the InsereVmedios function, you'll also need a corresponding free to de-allocate that memory again (otherwise you'd have a memory leak). You probably want to do that right before returning from the function.


>> And i also have to free the input_medios variable?

The input_medios function points to a block of memory that is already freed correctly by using free(buf) at the end of main. You should not de-allocate the same block of memory more than once - that's asking for trouble :)


>> But like i said maybe this are a newbie questions but i´m not confortable with C and less more with pointers and dynamic memory.

Practice makes perfect. By using dynamic memory allocation in your code, you'll get more and more comfortable with it. We've all had to learn how to use pointers and dynamically allocated memory correctly in C.
Thanks for the fast answer´s.


But i´m steel stuck again when try to free the v_medios.

Like you said i try to free the pointer v_medios at the end of the function, but no success. grrrrrr :(

Can you help me understand better how this works, or any good tutorial for me ( i have 6 years old, i´m kidding)

That's most likely because you don't allocate enough memory for v_medios :

>> 93:       v_medios=(float*) malloc(sizeof(float*)*i+1);

First of all, you need sizeof(float) instead of sizeof(float*), because you allocate memory for an array of float's, not pointers-to-float.
Next, you need ()'s around i+1. Otherwise, the +1 is performed after the multiplication.
Finally, you need to set i to a value that is big enough (instead of 0).
Thanks again.

What i do before you answer was, i pass the variable memUsada to the function where is the v_medios=(float*) malloc(sizeof(float*)*i+1);

And put like this v_medios=(float*) malloc(sizeof(float*)*memUsada); and did work. :)

But i don´t have the knowledge or skill yet to see if it´s well in programmatically way.

But the program run´s well now but if it is the wright way to do! hum i dont know.

Can you give your opinion as an expert?

Thanks a lot for your help and time.
Apart for the fact you still use sizeof(float*), your approach sounds reasonable - MemUsada is guaranteed to be big enough for the float array.
Thanks for your opinion.

I already change the sizeof(float*) to sizeof(float).