1

i'm learnig how to code in C. i have to create a record for a person, with an birthday and a ID number the code is composed of 3 files

the fist is a header

    // definição do tipo
typedef int vetor[10];

typedef struct 
{
    char nome[50];
    vetor nasceu;
    vetor cpf;
} dados ;

void cadastro (dados*, char[50], vetor, vetor);

then there is the definitions of the header

#include <stdio.h>
#include <string.h>
#include "cadastro.h"

void cadastro (dados *usuario, char name[50], vetor ddn, vetor cpf)
{
    int i;
    strcpy(usuario->nome,name);
    for (i = 0; i < 50; i++)
    {
        usuario->nasceu[i] = ddn[i];
    }
    for (i = 0; i < 10; i++)
    {
        usuario->cpf[i] = cpf[i];
    }
}

and the last file uses the header to generate the record

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cadastro.h"

int preenche_cadastro (char a[],vetor b,vetor c)
{
    int i;
    printf ("inserir nome: ");
    gets (a);
    printf("inserir data de nascimento (campos separados por espaco): ");
        for (i = 0; i < 3; i++)
        {
            scanf("%d",&b[i]);
        } 
    printf ("inserir CPF (campos separados por espaco): ");
    for (i = 0; i < 4; i++)
    {
        scanf("%d",&c[i]);
    }
    return (0);
}

int imprime_cadastro (dados usuario)
{
    printf("\nnome: %s",usuario.nome);
    printf("\ndata de nascimento: %d / %d / %d\n", usuario.nasceu[0],usuario.nasceu[1],usuario.nasceu[2]);
    printf("CPF:  %d . %d . %d - %d\n", usuario.cpf[0],usuario.cpf[1],usuario.cpf[2],usuario.cpf[3]);
    return(0);
}

int main(void) 
{
    dados new_entry;
    char name[50];
    vetor born, cpf;
    int i;
    preenche_cadastro (name,born,cpf);
    cadastro(&new_entry, name, born, cpf);
    imprime_cadastro(new_entry);
    return (0);
}

i don't really know how to debug, but as far as i could tell, the `Segmentation fault' occurs only at the line

return (0);

i'm going mad here, can anybody help me?

sorry for my english, it's not mother language

  • Note: `return` is a statement, not a function. The parenthesis are not required and deprecated by most programmers, because they make the code less readable. – too honest for this site Mar 15 '16 at 03:10
  • Not everyone deprecates parentheses around the expression after a `return` statement. And they don't materially affect the readability of the code. OTOH, the spacing should be consistent — consistency is very important. – Jonathan Leffler Mar 15 '16 at 04:10
  • 1
    See [Why the `gets()` function is to dangerous to be used](http://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used) for why you should never write any code that uses `gets()`. – Jonathan Leffler Mar 15 '16 at 04:12
  • Important to fix the `gets` problem, as any source of buffer overflow may lead to bizarre errors. – M.M Mar 15 '16 at 04:13

3 Answers3

3

Your first loop should only copy 10 items rather than 50.

    for (i = 0; i < 10; i++)
    {
        usuario->nasceu[i] = ddn[i];
    }
mattman
  • 366
  • 1
  • 9
3

You invoked undefined behavior by accessing out-of-range of array in the line

usuario->nasceu[i] = ddn[i];

in function cadastro, and then the program happened to crash there.

Do not invoke undefined behavior. Instead of using magic number 10, you should define the number of elements in the array and use it.

Also note that using values of uninitialized variables having automatic storage duration, which are indeterminate, also invokes undefined behavior.

corrected header:

// definição do tipo
#define VETOR_NUM 10
typedef int vetor[VETOR_NUM];

typedef struct 
{
    char nome[50];
    vetor nasceu;
    vetor cpf;
} dados ;

void cadastro (dados*, char[50], vetor, vetor);

corrected implementation of cadastro:

#include <stdio.h>
#include <string.h>
#include "cadastro.h"

void cadastro (dados *usuario, char name[50], vetor ddn, vetor cpf)
{
    int i;
    strcpy(usuario->nome,name);
    for (i = 0; i < VETOR_NUM; i++)
    {
        usuario->nasceu[i] = ddn[i];
    }
    for (i = 0; i < VETOR_NUM; i++)
    {
        usuario->cpf[i] = cpf[i];
    }
}

corrected main() function:

int main(void) 
{
    dados new_entry;
    char name[50];
    vetor born = {0}, cpf = {0}; /* initialize arrays */
    /* i is removed because it wasn't used */
    preenche_cadastro (name,born,cpf);
    cadastro(&new_entry, name, born, cpf);
    imprime_cadastro(new_entry);
    return (0);
}

One more note: You shouldn't use gets(), which has unavoidable risk of buffer overrun.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
2

This loop in your cadastro function:

for (i = 0; i < 50; i++)
{
    usuario->nasceu[i] = ddn[i];
}

Seems to not be in line with the size of the nasceu arrary:

typedef int vetor[10];

typedef struct 
{
    char nome[50];
    vetor nasceu;
    vetor cpf;
} dados ;

Have you tried changing to:

for (i = 0; i < 10; i++)
{
    usuario->nasceu[i] = ddn[i];
}

?

dovetalk
  • 1,995
  • 1
  • 13
  • 21