C - Dúvida com ponteiros

A professora pediu para fazer um trabalho para administrar estoque de uma loja utilizando C.

Tenho uma lista encadeada com os produtos, que estão ordenados por código (faço a ordenação no momento da inclusão).
No entanto, também preciso mostrar a lista por ordem de preço.

Pensei em utilizar um algoritmo de ordenação para ordenar a lista… mas vi que não teria sentido em uma lista encadeada…
Então, criei uma nova lista encadeada e faço a ordenação por preço no momento da inclusão.

Porém, me surgiram algumas dúvidas ao copiar as informações para essa nova lista.

  1. Quando vou copiar o produto para a nova lista eu aloco espaço na memória para criar uma estrutura diferente da lista original. Tem como eu copiar todas as informações da estrutura original, no entanto, com um espaço diferente na memória? (Porque não quero alterar a ordenação da lista inicial).

  2. Como não consegui copiar a estrutura inteira, copiei uma por uma das propriedades para criar uma estrutura nova. Porém, ao copiar o nome e fabricante que são do tipo char. Aparece a Warning LValue Required. Como posso contornar esse aviso?


typedef struct produto {

	//variaveis para armazenar informacoes do produto
	char nome[50];
	int codigo;
	char fabricante[50];
	Data dataDeAquisicao;
	int quantidadeNoEstoque;
	double precoDeVenda;

	//variavel para encadear a lista
	struct produto *proximo;

} Produto;

/**
*	Funcao utilizada para listar todos os produtos em ordem crescente
* 	de preco
*/
//InformacoesDoEstoque é o header da lista encadeada, tem o inicio da lista e o total de produtos
void listarTodosOsProdutos(InformacoesDoEstoque *informacoesDoEstoque) 
{
	Produto *iterador, *novoProduto, *produtoAnterior;

	//armazenar  a lista dos produtos em ordem crescente de preco
	Produto *produtosEmOrdemCrescenteDePreco = NULL;

	//criar uma lista dos precos em ordem crescente
	iterador = informacoesDoEstoque -> inicio;

	while( iterador != NULL )
	{
		//copiar informacoes do produto que esta no estoque
		//assim nao altero na memoria os produtos da lista original
		novoProduto = (Produto*) malloc(sizeof(Produto));
		novoProduto -> codigo = iterador -> codigo;
		novoProduto -> dataDeAquisicao = iterador -> dataDeAquisicao;
		novoProduto -> quantidadeNoEstoque = iterador -> quantidadeNoEstoque;
		novoProduto -> precoDeVenda = iterador -> precoDeVenda;
                novoProduto -> fabricante = iterador -> fabricante;
         //.... continua a função...
}

Isso porque você não pode copiar um array sobre o outro em C só usando o sinal de “=”.

Você, nesse caso, precisaria usar memcpy ou strncpy (não sei como é que você define o char nome[50], se é uma string terminada com “\0”, como é o padrão do C, ou se você completa tudo com espaços (esquemão banco de dados), até chegar à posição 50, e não usa “\0”.

Não funciona:

Produto p;
Produto q;
p.nome = q.nome;

Funciona:

Produto p;
Produto q;
memcpy (p.nome, q.nome, sizeof (p.nome));

Cuidado que se nome fosse um char*, em vez de um char[50], não poderia usar sizeof. Nesse caso, precisaria usar strncpy. OK?

Uma coisa que você tem de tomar um pouco de cuidado em C é que isto aqui funciona:

Produto p;
Produto q;
p = q; /* copia o valor de q na variável p */

mas isso é uma “shallow copy” ou “bitwise copy”, ou seja, tudo se comporta como se fosse:

memcpy (&p, &q, sizeof (p));

O Prof por um mero dos acaso é a Beatriz Lux?

Sim. Por?

A lista encadeada original está com dois nós:

Produto Código 1
Produto Código 10

Quando vou criar a nova lista acontece o seguinte:

novoProduto = (Produto*) malloc(sizeof(Produto));

Nesse momento:

[quote]iterador -> codigo = 1
iterador -> proximo -> codigo = 10[/quote]

A lista ainda está correta.

novoProduto -> codigo = iterador -> codigo;

Após passar pela linha acima.

[quote]iterador -> codigo = 1
iterador -> proximo -> codigo = 1[/quote]

Por que ao alterar o código do novoProduto que eu havia alocado um novo na memória. Alterou o proximo do inicio da lista? Pode ter ficado uma referencia a ele, mesmo tendo feito o malloc?

No erro acima consegui evitar o erro, usando uma variavel auxiliar:

[code]int codigo;

codigo = iterador -> codigo;
novoProduto -> codigo = codigo;[/code]

Mas ainda não consegui entender como novoProduto -> codigo = iterador -> codigo, altera o valor do iterador -> proximo -> codigo?