Doubt in code C data structure

0

Good afternoon, well I'm here to see if anyone knows why my code is printing a memory garbage, when it executes it shows what I want but printa trash of memory, if anyone knows why I thank

thesenumbersai"7304688"

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

typedef struct no

int codigo;
char nome[10];
struct no *next;
}no;

struct no *corrente, *auxiliar, *inicio;

int i;

int inserir (no *lista)
{
    for(i=1;i<=3;i++)
    {
        if(auxiliar==NULL){
            auxiliar = (no*)malloc(sizeof(no));
            auxiliar->next = NULL;
            corrente = auxiliar;
            inicio = auxiliar;
        }
        else{
            auxiliar = (no*)malloc(sizeof(no));
            corrente->next=auxiliar;
            auxiliar->next = NULL;
            corrente = auxiliar;
            fflush(stdin);
            printf("Entre com o codigo:\n");
            scanf("%d",&auxiliar->codigo);
            fflush(stdin);
            printf("Entre com o nome:\n");
            scanf("%s",&auxiliar->nome);
        }
    }
}



int exibir(no *lista)
{

    if(inicio==NULL){

        printf("Lista Vazia\n");
        system("pause");
    }
    else{
        corrente = inicio;
        //system("cls");
        //printf("\tDados a ser mostrados...");
        //sleep(5);
        //system("cls");


        while(corrente!=NULL){

            printf("%d\n",corrente->codigo);
            printf("%s\n",corrente->nome);
            corrente = corrente->next;

        }
        system("pause");
    }
}

int main (){

    auxiliar = NULL;
    corrente = NULL;
    inicio = NULL;
    int tecla=1;


    printf("Programando dinamicamente:\n");
    printf("Aplicando encadeamento...\n");

    while(tecla!=0){
        printf("Digite\n \n1-Inserir \n2-Mostrar\n");
        scanf("%d",&tecla);


        switch(tecla){
            case 1: inserir(&inicio);
            break;
            case 2: exibir(&inicio);
            break;
            default: printf("Opcao Invalida");
            break;
        }
    }
    return 0;

}
    
asked by anonymous 08.03.2017 / 19:48

1 answer

1

Where to start?

First, avoid using global variables whenever you can . In particular, setting a global int i to use as a loop index gets you into an endless mess, since you always have to remember if some other function calling your current function uses that same variable to control your loop . Since here only inserir() uses the variable i , this will not happen for the moment, but at the same time it is unjustifiable to be global if only one function should see it.

Second, at the time of scanf() , always start the string format with a space for the CRT to "eat" extra characters as carriage returns. When reading a string, always use the precision specifier so that the buffer does not pop: then scanf(" %.9s", &(auxiliar->nome)); on line 35, for example (note that we are prompted to write < in> maximum 9 carecters, so that the tenth contains the '\ 0').

Thirdly, you pass a no * lista parameter to both inserir() and exibir() , and then solemnly ignores the parameters you passed in favor of global references *inicio , *corrente and *auxiliar . Create instead a local variable of type no * and use it instead of corrente , initializing it with the value of inicio at the beginning of the function.

It has other things, but none of it makes your code print the rubbish. What it does is inserir() : you noticed that it has a loop for(i=1;i<=3;i++) , but when you run option 1 for the first time it only requests two names? Let's do a Chinese insert:

  • The function starts. i = ???, inicio = NULL, corrente = NULL, auxiliar = NULL .
  • Enter the loop . i = 1, inicio = NULL, corrente = NULL, auxiliar = NULL .
  • if : as auxiliar == NULL , enter "then".
  • auxiliar is allocated. i = 1, inicio = NULL, corrente = NULL, auxiliar = { .codigo = ???, .nome = ???, next = ??? } .
  • the auxiliar->next is displayed. i = 1, inicio = NULL, corrente = NULL, auxiliar = { .codigo = ???, .nome = ???, next = NULL } .
  • the corrente is displayed. i = 1, inicio = NULL, corrente = { .codigo = ???, .nome = ???, next = NULL }, auxiliar = { .codigo = ???, .nome = ???, next = NULL } .
  • the inicio is displayed. i = 1, inicio = { .codigo = ???, .nome = ???, next = NULL }, corrente = { .codigo = ???, .nome = ???, next = NULL }, auxiliar = { .codigo = ???, .nome = ???, next = NULL } .
  • end loop , increment, test. Loop continues. i = 2, inicio = { .codigo = ???, .nome = ???, next = NULL }, corrente = { .codigo = ???, .nome = ???, next = NULL }, auxiliar = { .codigo = ???, .nome = ???, next = NULL } .
  • auxiliar != NULL , then you go to else . i = 1, inicio = { .codigo = ???, .nome = ???, next = NULL }, corrente = { .codigo = ???, .nome = ???, next = NULL }, auxiliar = { .codigo = ???, .nome = ???, next = NULL } .
  • A new auxiliar is added, without any data. i = 1, inicio = { .codigo = ???, .nome = ???, next = NULL }, corrente = { .codigo = ???, .nome = ???, next = NULL }, auxiliar = { .codigo = ???, .nome = ???, next = ??? } .
  • You set the corrente->next to the new auxiliar and then you start filling in your fields. i = 2, inicio = { .codigo = ???, .nome = ???, next = &auxiliar }, corrente = { .codigo = ???, .nome = ???, next = &auxiliar }, auxiliar = { .codigo = 1234, .nome = "joao", next = NULL } .
  • Can you see the pattern? The first link of the list had neither codigo nor nome initialized. Then it prints the garbage that was in codigo and the garbage that was in nome (in my case, thank God, it immediately found a 0 byte and printed an empty string . p>

    What to do, then?

    Reboot your inserir to test the existence of auxiliar before entering the loop , and then load the information in all iterations of for . So it will stop inserting junk.

        
    09.03.2017 / 20:06