Accessing the allocation makes Program stop working

I'm having a problem accessing a struct of subscribers

typedef struct Inscrito {
     char nome[50];
     float cadastro;
     float nota;
};

Inscrito *inscritos = NULL;

It is as a global variable and every time I access it in some way (either to check for an error or to put the values inside it after allocating it from the error)

(data is the variable of the file .txt that I opened)

int Conta_MaioresNotas(FILE *Dados){

float NotaMin;
char info[20];
float numero;
int contador = 0, i = 0;

printf("Voce escolheu as maiores notas\n");
printf("Apartir de qual nota voce quer? ");
scanf("%f", &NotaMin);

while(!feof(Dados)){
    fscanf(Dados,"%s", &info);
    numero = atof(info);
    if(numero && numero > NotaMin && numero < 1001){
        contador++;
        printf("%.2f\n", numero);
    }
}
printf("%d\n", contador);
VoltaInicio(Dados);


inscritos = (Inscrito *) malloc(contador*sizeof(Inscrito));

if(inscritos == NULL) {printf("Deu erro meu amigo\n"); exit(-1);}


 while(!feof(Dados)){
    fscanf(Dados,"%s ", &info);
    numero = atof(info);
    if(!numero){
        strcat(inscritos[i].nome, " ");
        strcat(inscritos[i].nome, info);
        }
    else{
        if(numero > 1000){
            inscritos[i].cadastro = numero;

            }
        else{
            if(numero > NotaMin){
                inscritos[i].nota = numero;
                i++;
                }
            else{
                strcpy(inscritos[i].nome,"");
                inscritos[i].cadastro = 0.0;
                }
            }
        }    
}
VoltaInicio(Dados);

That while giving the error, but not understanding why, the program sticks and closes "the program stopped working. A problem caused the program stops working "

/*printf("Cadatrados filtrados:\n");
for(i = 0; i < contador; i++)
{
    printf("Nome: %s\nCadastro: %f\nNota: %.2f\n\n", inscritos[i].nome, inscritos[i].cadastro, inscritos[i].nota);
}*/


return contador;
}

I commented This for to show that it is not he that giving error, so to be able to show the code until the end

insert the description of the image here (I already tried to pass the subscribed pointer to the function and gave the same error)

Author: Thiago Moreira, 2018-04-07

1 answers

The way the code was presented is a little difficult to determine with certainty what the problem is, even why it was not fully informed, but there are some considerations.

First of all, I do not encourage the use of global variables. I understand the ease this provides but you can be responsible for these errors if you don't pay attention to what you do. It is important to note that global variables can be changed anywhere, so it is very easy for you to end up releasing or overwriting global variable data through an unplanned execution flow. Develop your software keeping in mind the paths in which the code can be executed. Make your functions perform only a task, and not functions that do everything that is to be done.

As for the code presented, I first believe that it did not copy directly from what it did because there is an error right in the statement of struct , when using this notation of struct with typedef (which is commendable, I appreciate the practice as you did), it is necessary to define the new name after the end of the statement of struct , before the semicolon, in your example:

typedef struct Instrucao{
  ...
} Instrucao; //<---Erro

Just so the example provided would no longer run, but I don't believe that to be the case.

I also don't believe this to be the case of memory release, but keep in mind that you should release the memory allocated in the variable statements using the function free () , due to the dynamic allocation performed.

As for your specific error, you should also note that within the while that you suspect has an error, you use the function strcat, and it, as the name says, performs a concatenation of strings. Initially the name in question is empty, it has absolutely nothing, so there is a small problem in wanting to concatenate a string to nothing, the value is literally empty, but most compilers won't complain about this superficially, if you use an execution parser like valgrind, you'll notice that it will complain about some instruction-related errors that depend on memory that hasn't been initialized yet (your string before concatenating anything).

This concatenation is also dangerous because the variable name in its struct instruction has been declared to have a maximum size of 50 characters, so it is possible that any of the concatenations you are performing exceed 50 characters, which means that one of the names has more than 50 characters, or an improper concatenation is happening and exceeding the character limit you have allocated, causing what is called stack smashing, basically you are using more characters than you reported.

If the problem is not in the name in the instructions, it can be in the character vector info, which supports only 20 characters, then one of the names or surnames may exceed 20 characters and cause the error reported.

It turns out that not always exceeding the size you have allocated will cause an error like this, what happens is a undefined behavior or undefined behavior, sometimes it can work, sometimes not, it will be variable depending on the execution of your program and therefore it will not be reliable to use it. It is important that you change these strings to a dynamic allocation or increase their size to see if this solves the problem in question.

 0
Author: Zeero, 2018-04-08 02:02:04