Ir ao conteúdo
  • Cadastre-se

C Realocamento interferindo em outras partes da memória (?)


milhodasilva

Posts recomendados

Olá pessoal, estou estudando alocamento dinâmico e não consigo achar o erro nesse cód.

Ele é um cadastro de carros com modelo, ano e valor. O que eu acho que está acontecendo é que ao realocar dentro do laço while pela segunda vez, ele compromete parte do bloco do cadastro do primeiro carro, ao realocar pela terceira, compromete a do segundo carro, e assim por diante. Se alguém puder me dar uma luz, agradeço. (Recomendo não usarem o dev, haha).

#include <stdio.h>
#include <stdlib.h>

typedef struct{
	char modelo[30];
	int ano;
	float valor;
}t_carro;

int main(int argc, char *argv[]) {
	int i, qte = 0;
	char opcao;
	t_carro *pc; //cria ponteiro para tipo t_carro

	system("color 70");		 				//cor da tela
	pc = malloc(sizeof(t_carro));				//aloca espaco de tamanho correspondente ao da struct, para o qual pc aponta
	puts("informe modelo, ano e valor");
	fflush(stdin); gets(pc->modelo);			//Pega o valor correspondente ao modelo da struct que pc aponta
	fflush(stdin); scanf("%d",&pc->ano);		//Pega o valor correspondente ao ano da struct que pc aponta
	fflush(stdin); scanf("%f",&pc->valor);		//Pega o valor correspondente ao valor da struct que pc aponta
	qte++;												//após cadastrar - contabiliza um carro cadastrado (qte = quantidade)

	printf("\nModelo: %s\nAno:%d\nValor: %f\n",pc->modelo,pc->ano,pc->valor);
	puts("\nDeseja cadastrar outro? s/n");
	fflush(stdin); scanf("%c", &opcao);

	while(opcao == 's'){
		qte++;								//A quantidade aumenta
		realloc(pc, qte*sizeof(t_carro));     //Precisará de mais espaço -> realocará para que: espaço = quantidade de carros atual * tamanho da struct
		//printf("modelo: %s\n ano:%d\n valor: %f\n",pc->modelo,pc->ano,pc->valor);

		pc++;                                 //move o ponteiro uma casa a frente, para salvar o carro (equivalente a um i++ se fosse pc[i])

		puts("\nInforme modelo, ano e valor");
		fflush(stdin); gets(pc->modelo);
		fflush(stdin); scanf("%d", &pc->ano);
		fflush(stdin); scanf("%f", &pc->valor);

		printf("\nModelo: %s\nAno:%d\nValor: %f\n", pc->modelo, pc->ano, pc->valor);

        //printf("\nALOHA: %d\n", ((pc-2)->ano));   // teste

		puts("\nDeseja cadastrar outro? s/n");
		fflush(stdin); scanf("%c", &opcao);
	}

	pc -= qte-1; 				//Para imprimir as informaçoes desde o inicio, subtrai a quantidade cadastrada, mas soma 1 para chegar ao primeiro.
	for(i = 0; i < qte; i++){
		printf("\n--- Carro numero %d ---", i+1);
		printf("\nModelo: %s\nAno:%d\nValor: %f\n", pc->modelo, pc->ano, pc->valor);
		pc++;
	}

	return 0;
}

 

carros.txt

Link para o comentário
Compartilhar em outros sites

11 minutos atrás, isrnick disse:

Mude:


realloc(pc, qte*sizeof(t_carro));

 

Para:


pc = realloc(pc, qte*sizeof(t_carro));

 

E não incremente nele...

pc++;

 

Acesse usando índices:


pc[qte-1]->modelo

 

 

Obrigada pela sugestão, foi exatamente o que fiz essa manhã, com ajuda de um colega, funcionou bem. De qualquer forma, eu gostaria de saber porque usando pc++ dá errado  😕

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, milhodasilva disse:

De qualquer forma, eu gostaria de saber porque usando pc++ dá errado

 

Porque nada garante que por exemplo a área apontada a partir de pc possa ser estendida por quando você tenha pedido.

Por essa razão realloc() devolve um ponteiro para uma nova área, que tem o tamanho que você precisa. E isso pode ter implicado em copiar todo o bloco previamente alocado a partir de pc para o novo endereço, que a função vai te devolver. Se você não salvar, já era. Alocado foi. Acessível não é. Devia dar erro mas não dá. E se continuar usando o mesmo endereço base de antes, pc, como fazia, mais cedo ou mais tarde seu programa vai abortar por tentar acessar além do que tinha sido previamente alocado.

 

E como eu disse, manipular esse valor --- pc++ por exemplo --- quase sempre vai cancelar seu programa ou mesmo seu sistema. Imagine quando você for liberar essa região: vai chamar free(0 usando qual endereço, já que perdeu esse? 

 

Sugiro de novo:  não use isso. Use estruturas de dados mais sofisticadas, como listas, árvores, vetores de ponteiros e tal. realloc() tem esses efeitos colaterais.

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

2 horas atrás, milhodasilva disse:

 

Obrigada pela sugestão, foi exatamente o que fiz essa manhã, com ajuda de um colega, funcionou bem. De qualquer forma, eu gostaria de saber porque usando pc++ dá errado  😕

 

Ao fazer pc++ você altera pc, mas então você tenta realocar usando essa posição incrementada ao fazer realloc(pc, qte*sizeof(t_carro)); , o que vai dar erro pois pc não aponta mais para a posição original da memória que foi alocada com malloc.

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...