Ir para conteúdo
Brunow0

Alocação de memória ajuda

Recommended Posts

Preciso sabe se estou alocando memória corretamente no meu código. Conto com a ajuda de vocês!

O exercício pede o seguinte:

Crie um programa de cadastro simples de agenda (em memória) com inclusão de novas entradas e alteração, consulta, exclusão e pesquisa (ordenada) de entradas já existentes.

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int op=0,op1,qcad=0,i=0,x,y;
char name[50];
struct contato
{
char nome[50];
char email[50];
char telefone[15];
};
void cadastrar (struct contato *c)
{
    printf("\nDigite o nome: ");
    gets(c.nome);
    strupr(c.nome);
    printf("Digite o email: ");
    gets(c.email);
    printf("Digite o telefone: ");
    gets(c.telefone);
    i++;
    do
    {
    printf("\nDeseja cadastrar mais? \n1-SIM \n2-NAO\n");
    scanf("%d%*c", &op1);
    fflush(stdin);
        if (op1==1)
        {
        c=(struct contato*)(realloc(c,(qcad+1)*sizeof(struct contato)));
            if (c==NULL)
            {
            printf("\n ERRO // MEMORIA INSUFICIENTE");
            exit(1);
            }
            qcad++;
            cadastrar(c);
        }
    }while (op1!=2);
}
void altera (struct contato *c)
{
    printf("Digite o nome: ");
    gets(name);
    strupr(name);
    for (x=0,y=-1;x<i;x++)
    {
        if (strcmp(name,c[x].nome)==0)
        {
        y=x;
        }
    }
    if(y<0)
        {
        printf("\nNOME NAO CADASTRADO\n\n");
        system("pause");
        }
    else
        {
        printf("\nDigite o novo nome: ");
        gets (c[y].nome);
        strupr(c[y].nome);
        fflush(stdin);
        printf("\nDigite o novo email: ");
        gets (c[y].email);
        fflush(stdin);
        printf("\nDigite o novo telefone: ");
        gets(c[y].telefone);
        fflush(stdin);
        }
}
void ordena (struct contato *c)
{
    char nomeaux[50];
    char emailaux[50];
    char telefoneaux[15];
    for (x=1;x<i;x++)
    {
        for (y=x;y>0;y--)
        {
            if (strcoll(c[y].nome, c[y-1].nome) < 0)
            {
                strcpy(nomeaux,c[y].nome);
                strcpy(emailaux,c[y].email);
                strcpy(telefoneaux,c[y].telefone);
                strcpy(c[y].nome,c[y-1].nome);
                strcpy(c[y].email,c[y-1].email);
                strcpy(c[y].telefone,c[y-1].telefone);
                strcpy(c[y-1].nome,nomeaux);
                 strcpy(c[y-1].email,emailaux);
                  strcpy(c[y-1].telefone,telefoneaux);
            }
        }
    }
}
void consulta(struct contato *c)
{
     if (i==0)
    {
    printf("\nNENHUM CADASTRO\n\n");
    system("pause");
    }
    else
    {
        ordena(c);
        for (x=0;x<i;x++)
        {
        printf("\n NOME: %s ",c[x].nome);
        printf("\n EMAIL: %s ",c[x].email);
        printf("\n FONE: %s \n",c[x].telefone);
        system("pause");
        }
    }
}
void exclui(struct contato *c)
{
    for (x=0,y=-1;x<i;x++)
    {
        if (strcmp(name,c[x].nome)==0)
        {
        y=x;
        }
    }
        if(y<0)
        {
        printf("O nome nao existe\n");
        }
        else
        {
        printf("Deseja excluir? \n1 - SIM \n2 - NAO\n");
        scanf("%d%*c",&op1);
            if (op1==1)
            {
            strcpy(c[y].nome,c[i-1].nome);
            strcpy(c[y].email,c[i-1].email);
            strcpy(c[y].telefone,c[i-1].telefone);
            i--;
            c=(struct contato*)(realloc(c,(i)*sizeof(struct contato)));
            qcad--;
            printf("EXCLUIDO COM SUCESSO\n");
            }
        }
}
void pesquisa(struct contato *c)
{
     printf("Digite o nome: ");
     gets(name);
     strupr(name);
    for (x=0,y=-1;x<i;x++)
        {
            if (strcmp(name,c[x].nome)==0)
            {
            y=x;
            }
        }
            if(y<0)
            {
            printf("O nome nao existe\n");
            system("pause");
            }
            else
            {
            printf("\n NOME: %s ",c[y].nome);
            printf("\n EMAIL: %s ",c[y].email);
            printf("\n FONE: %s \n",c[y].telefone);
            exclui(c);
            system("pause");
            }
}
void menu()
{
    struct contato *c=(struct contato*)malloc(qcad*sizeof(struct contato));
     if (c==NULL)
    {
        printf("\n ERRO // MEMORIA INSUFICIENTE");
        exit(1);
    }
    do
    {
    system("cls");
    op=-1;
    printf("******MENU******\n");
    printf("1 - Cadastrar \n2 - Alterar \n3 - Consultar \n4 - Excluir \n5 - Pesquisar \n9 - Sair\n");
    printf("****************\n");
    scanf("%d%*c", &op);
    switch (op)
    {
        case 1:
            c=(struct contato*)(realloc(c,(qcad+1)*sizeof(struct contato)));
            if (c==NULL)
            {
            printf("\n ERRO // MEMORIA INSUFICIENTE");
            exit(1);
            }
            qcad++;
            cadastrar(c);
            break;
        case 2:
                altera(c);
                break;
        case 3:
               consulta(c);
                break;
        case 4:
                printf("Digite o nome: ");
                gets(name);
                strupr(name);
                fflush(stdin);
                exclui(c);
                if (i==0)
                {
                c=(struct contato*)(realloc(c,(qcad+1)*sizeof(struct contato)));
                }
                system("pause");
                break;
        case 5:
           pesquisa(c);
           if (i==0)
                {
                c=(struct contato*)(realloc(c,(qcad+1)*sizeof(struct contato)));
                }
                    break;
        case 9:
            return 0;
            break;
        default:
            puts("Opcao invalida!!!\n\n\n");
            system("pause");
    }
    }while (op!=9);
}

int main()
{
    menu();
    return 0;
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Na função cadastrar sempre que é inserido um novo registro o programa grava na primeira posição o que fará com que ao consultar somente apareça o último por que os outros estarão sobrescritos. Deve-se mover o ponteiro da lista antes de gravar novos.

 

Nas linhas:

 

scanf ( "%d%*c" , & op1 ); 
fflush ( stdin); 

 

há uma redundância por que o formatador %*c que serve para eliminar o retorno de carro da fila de caractéres de entrada de teclado é seguido pelo comando fflush(stdin) que têm a mesma função ordenando o computador a fazer duas vezes a mesma coisa. Desnecessariamente por que só com o %*c o retorno de carro já é eliminado.

 

Nesse programa dispensa-se o uso da variável op1 já que toda vez que o usuário optar pode-se usar a mesma variável op. Removendo op1 irá resultar em economia de código e de memória RAM.

 

Toda vez que a memória é realocada é usado um ponteiro diferente com o mesmo nome para receber a porção de memória. Isso vai gerar resultados incorretos por que toda vez que realocar irá devolver a memória para um ponteiro diferente. Deve-se usar somente um ponteiro.

 

Nos cases 4 e 5 não é necessário realocar o ponteiro por que toda vez que opta por cadastrar um novo ele já faz isso e também não precisa da função fflush(stdin) pois o comando gets não deixa o retorno de carro na fila e o mesmo vale para a leitura de nome, e-mail e telefone da função altera.

 

No case 9 da função menu pode-se retirar o comando break. Ao usuário digitar 9 o programa já irá sair do bloco de código switch devido ao comando de retorno de função.

 

O seu código reaproveitado e com as modificações que eu falo:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int op = 0 , qcad = 0 , i = 0 , x , y ;
char name [ 50 ];
struct contato
{
char nome [ 50 ];
char email [ 50 ];
char telefone [ 15 ];
} * c;
void cadastrar ()
{
    printf ( "\nDigite o nome: " );
gets ( c[ i ]. nome );
strupr ( c[ i ]. nome );
printf ( "Digite o email: " );
gets ( c[ i ]. email );
printf ( "Digite o telefone: " );
gets ( c[ i ]. telefone );
i ++;
do
{
printf ( "\nDeseja cadastrar mais? \n1-SIM \n2-NAO\n" );
scanf ( "%d%*c" , & op );
if ( op == 1 )
{
c =( struct contato *)( realloc ( c ,( qcad + 1 )* sizeof
( struct contato )));
if ( c == NULL )
{
printf ( "\n ERRO // MEMORIA INSUFICIENTE" );
exit ( 1 );
}
qcad ++;
cadastrar ();
}
} while ( op != 2 );
}
void altera ()
{
    printf ( "Digite o nome: " );
gets ( name );
strupr ( name );
for ( x = 0 , y =- 1 ; x < i ; x ++)
{
if ( strcmp( name , c
[ x ]. nome )==0 )
{
y = x ;
}
}
if ( y < 0 )
{
printf ( "\nNOME NAO CADASTRADO\n\n" );
system ( "pause" );
}
else
{
printf ( "\nDigite o novo nome: " );
gets ( c [ y ]. nome );
strupr ( c [ y ]. nome );
printf ( "\nDigite o novo email: " );
gets ( c [ y ]. email );
printf ( "\nDigite o novo telefone: " );
gets ( c [ y ]. telefone );
}
}
void ordena ()
{
char nomeaux [ 50 ];
char emailaux [ 50 ];
char telefoneaux [ 15 ];
for ( x = 1 ; x < i ; x ++)
{
for ( y = x ; y > 0 ; y --)
{
if ( strcoll ( c
[ y ]. nome , c [ y - 1 ]. nome ) < 0 )
{
strcpy ( nomeaux , c
[ y ]. nome );
strcpy
( emailaux , c [ y ]. email );
strcpy
( telefoneaux , c [ y ]. telefone );
strcpy ( c
[ y ]. nome , c [ y - 1 ]. nome );
strcpy ( c
[ y ]. email , c [ y - 1 ]. email );
strcpy ( c
[ y ]. telefone , c [ y - 1 ]. telefone );
strcpy ( c
[ y - 1 ]. nome , nomeaux );
strcpy ( c
[ y - 1 ]. email , emailaux );
strcpy ( c
[ y - 1 ]. telefone , telefoneaux );
}
}
}
}
void consulta ()
{
if ( i == 0 )
{
printf ( "\nNENHUM CADASTRO\n\n" );
system ( "pause" );
}
else
{
ordena ();
for ( x = 0 ; x < i ; x ++)
{
printf ( "\n NOME: %s " , c
[ x ]. nome );
printf ( "\n EMAIL: %s " , c
[ x ]. email );
printf ( "\n FONE: %s \n" , c [ x ]. telefone );
system ( "pause" );
}
}
}
void exclui ()
{
for ( x = 0 , y =- 1 ; x < i ; x ++)
{
if ( strcmp( name , c
[ x ]. nome )==0 )
{
y = x ;
}
}
if ( y < 0 )
{
printf ( "O nome nao existe\n" );
}
else
{
printf ( "Deseja excluir? \n1 - SIM \n2 - NAO\n" );
scanf ( "%d%*c" ,& op );
if ( op == 1 )
{
strcpy ( c [ y ]. nome , c
[ i - 1 ]. nome );
strcpy ( c [ y ]. email , c
[ i - 1 ]. email );
strcpy ( c
[ y ]. telefone , c [ i - 1 ]. telefone );
i --;
c =( struct contato *)( realloc ( c ,( i )* sizeof( struct contato )));
qcad --;
printf ( "EXCLUIDO COM SUCESSO\n" );
}
}
}
void pesquisa ()
{
     printf ( "Digite o nome: " );
gets ( name );
strupr ( name );
for ( x = 0 , y =- 1 ; x < i ; x ++)
{
if ( strcmp( name , c
[ x ]. nome )==0 )
{
y = x ;
}
}
if ( y < 0 )
{
printf ( "O nome nao existe\n" );
system ( "pause" );
}
else
{
printf ( "\n NOME: %s " , c [ y ]. nome );
printf ( "\n EMAIL: %s " , c [ y ]. email );
printf ( "\n FONE: %s \n" , c [ y ]. telefone );
exclui ( c );
system ( "pause" );
}
}
void menu ()
{
c =( struct contato *) malloc( qcad * sizeof
( struct contato ));
if ( c == NULL )
{
printf ( "\n ERRO // MEMORIA INSUFICIENTE" );
exit ( 1 );
}
do
{
system ( "cls" );
op =- 1 ;
printf ( "******MENU******\n" );
printf ( "1 - Cadastrar \n2 - Alterar \n3 - Consultar \n4 - Excluir \n5 - Pesquisar \n9 - Sair\n" );
printf ( "****************\n" );
scanf ( "%d%*c" , & op );
switch ( op )
{
case 1 :
c =( struct contato *)( realloc ( c ,( qcad + 1 )* sizeof
( struct contato )));
if ( c == NULL )
{
printf ( "\n ERRO // MEMORIA INSUFICIENTE" );
exit ( 1 );
}
qcad ++;
cadastrar ();
break ;
case 2 :
altera ( c );
break ;
case 3 :
consulta ( c );
break ;
case 4 :
printf ( "Digite o nome: " );
gets ( name );
strupr ( name );
exclui ( c );
system ( "pause" );
break ;
case 5 :
pesquisa ( c );
break ;
case 9 :
return 0 ;
default :
puts ( "Opcao invalida!!!\n\n\n" );
system ( "pause" );
}
} while ( op != 9 );
}
int main ()
{
    menu ();
return 0 ;
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante
Este tópico está impedido de receber novos posts.

  • Conteúdo Similar

    • Por paulopoxoreo1234@gmail.com
      Dado o trecho de código em C listado abaixo responda as perguntas a seguir.
      Cont = result = 1;
      For ( i=0; i<5; i= i+0.1){
            Cont = cont+i;
            Result  *= cont;
            Printf(“%f", result);
      }
      a)      O que será impresso depois da primeira iteração deste código?
      b)      Quantas vezes este laço precisará ser executado para que encontre a condição de término ?
      c)      Faça um trecho de código em C para quebrar esse laço na decima quinta iteração.
    • Por ednan
      estou precisando de ajuda neste trabalho se alguem souber e puder ajudar agradeço de coraçao
       
    • Por Hokage1
      Boa Tarde estou quebrando a cabeça com um trabalho, podem me ajudar ?:
       
      ara execução do projeto final siga as instruções: 
       
      (Tarefa 1) Elaborar um programa em Linguagem de Programação C com 2 interfaces (telas); uma para o cadastro dos 10 estudantes e outra para os dados analíticos. (Tarefa 2) Somente após finalizar a Tarefa 1, faça uma investigação para identificar quais recursos (não abordados nesta disciplina), em Linguagem de Programação C, que poderiam tornar a construção desta aplicação mais sofisticada e, até mesmo, mais fácil de implementar? Explique (não há necessidade de implementar o novo recurso). Enviar a resposta da Tarefa 1 (código-fonte escrito em Linguagem de Programação C) e da Tarefa 2 para avaliação em um arquivo no formato MS-Word com nome no seguinte padrão: LCC-IA-2020-3-Mod3-Projeto-Seu_Nome.docx (Arquivos nomeados fora deste padrão serão descartados). Use o fórum do Módulo 03 para postar suas dúvidas e/ou colaborar com os colegas.  
      TAREFA 1 – Programa de cadastro e análise de dados de 10 Estudantes:
      1.Tela: Criar a tela a seguir que permita a entrada de dados de 10 estudantes diferentes. Assim que o usuário digitar os dados do último estudante, o programa deverá ir para a 2.tela.
      Tela 1 – Interface (Tela) para cadastro de 10 estudantes
      2.Tela: Criar a tela a seguir que apresente os dados analíticos, a partir dos dados digitados na Tela 1. Na sequência, encerrar o programa.
       
      tela 2 – Interface (Tela) do quadro analítico
      OBSERVAÇÕES:
      Todos indicadores do Quadro Analítico deverão ser calculados (nenhum digitado pelo usuário);
       
      A “Maior Nota Individual” deverá ser a maior nota obtida por um estudante em qualquer uma das 2 avaliações; A “Menor Nota Individual” deverá ser a menor nota obtida por um estudante em qualquer uma das 2 avaliações; A “Média da Sala” deverá ser a média das médias dos 10 estudantes; A “Melhor Média da Sala” deverá ser a maior média obtida por 1 estudante; A “Pior Média da Sala” deverá ser a menor média obtida por 1 estudante.
    • Por sidius
      ei galera, minha professora pediu para que eu calculasse matrizes utilizando a linguagem c, poderiam me dar uma luz ae?? ficaria grato, tenho grande dificuldade no assunto

    • Por juliaKrunker
      1- O comando typedef pode ser utilizado para criar novos comandos, ou simplesmente novas formas de escrever
      determinados comandos em linguagem C. Por exemplo, toda vez que você quiser criar uma variável do tipo struct
      declarado acima, terá que escrever o nome completo do tipo, isto é struct lista. Usando o comando typedef, defina um
      tipo alternativo, chamado Lista, que possa ser usado em lugar de struct lista.

      2-  Usando o tipo Lista que você criou na questão 3, declare uma variável chamada myList que possa ser utilizada para
      construir uma lista encadeada.
       
      3- (0,5) Usando o tipo Lista que você criou na questão 3, declare uma variável chamada novo que possa ser utilizada para criar
      um novo elemento para a lista declarada na questão 4.

      4- Escreva uma linha de código que aloque espaço na memória para a variável novo declarada na questão 5, de forma
      que a variável possa ser utilizada para inserir um novo elemento na lista myList declarada na questão 4.

      5 -Considerando a variável myList declarada na questão 4 e a variável novo declarada na questão 5 e alocada na questão
      6, atribua os valores 1 para o atributo id e 9.1 para o atributo valor e insira-a na lista myList.
       
      6- O trecho de código apresentado a seguir, refere-se a uma função que receberá como parâmetro um ponteiro para
      uma lista do tipo Lista e deverá calcular e retornar a média dos valores existentes na lista. Escreva o corpo da função.

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.