I am writing a simple program that at first checks a file for the number of structures present and allocates memory accordingly, then allows the user to insert new registries and allocates memory for those as well. Before program is terminated, all the data is saved to a binary file. I am able to insert up to 8 "servidor", but no more. When debugging, I found that after 8 entries, the program fails to realloc for a 9th, which indicates memory problems.
Call Stack
ntdll.dll!ntdll!RtlRaiseException (Unknown Source:0)
ntdll.dll!ntdll!RtlIsZeroMemory (Unknown Source:0)
ntdll.dll!ntdll!RtlIsZeroMemory (Unknown Source:0)
ntdll.dll!ntdll!.misaligned_access (Unknown Source:0)
ntdll.dll!ntdll!.misaligned_access (Unknown Source:0)
ntdll.dll!ntdll!.misaligned_access (Unknown Source:0)
ntdll.dll!ntdll!RtlReAllocateHeap (Unknown Source:0)
ntdll.dll!ntdll!RtlReAllocateHeap (Unknown Source:0)
AcLayers.dll!NotifyShims (Unknown Source:0)
msvcrt.dll!realloc (Unknown Source:0)
main() (c:\Users\tiago\Desktop\c.c:145)
Steps to reproduce
- Compile
- Run
- Insert many registries by typing 1 and typing a name.
- Program should fail at about 8 insertions, reverting file back to previous saved state, or 0.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
typedef struct Servidor
{
bool ocupado;
int codigo;
char nome[256];
} servidor;
int escrever_arquivo(void * _struct, size_t tam_struct, int tamanho)
{
FILE *fptr = fopen("data.bin", "w");
if(fptr == NULL)
{
return 1;
}
fwrite(_struct, tam_struct * tamanho, 1, fptr);
fclose(fptr);
}
int ler_arquivo(void * _struct, size_t tam_struct, int tamanho)
{
FILE *fptr = fopen("data.bin", "r");
if(fptr == NULL)
{
return 1;
}
fread(_struct, tam_struct * tamanho, 1, fptr);
fclose(fptr);
}
int busca_tamanho()
{
FILE *fptr = fopen("data.bin", "a");
if(fptr == NULL)
{
printf("Erro na abertura do arquivo!\n");
exit(1);
}
fseek(fptr, 0L, SEEK_END);
int tamanho = ftell(fptr);
fclose(fptr);
return tamanho / sizeof(servidor);
}
int busca_livre(servidor * grupo, int tamanho)
{
for(int i = 0; i < tamanho; i++)
{
if(grupo[i].ocupado != true)
{
return i;
}
}
}
void inserir_servidor(servidor * grupo, int tamanho)
{
if(!tamanho)
{
grupo[0].ocupado = true;
grupo[0].codigo = 0;
printf("Nome: ");
fgets(grupo[0].nome, sizeof(grupo[0].nome), stdin);
fflush(stdin);
}
else
{
int pos = busca_livre(grupo, tamanho);
grupo[pos].ocupado = true;
grupo[pos].codigo = pos;
printf("Nome: ");
fgets(grupo[pos].nome, sizeof(grupo[pos].nome), stdin);
fflush(stdin);
}
}
void imprimir_servidor(servidor * grupo, int tamanho)
{
for(int i = 0; i < tamanho; i++)
{
printf("%s %d\n\n", grupo[i].nome, grupo[i].codigo);
}
}
int main()
{
servidor * grupo;
int tamanho = busca_tamanho();
int memoria = tamanho * sizeof(servidor);
if(tamanho)
{
grupo = malloc(memoria);
ler_arquivo(grupo, sizeof(servidor), tamanho);
}
char input;
printf("memoria inicial: %d B , tamanho: %d\n\n", memoria, tamanho);
do
{
printf("1. Inserir servidor\n");
printf("2. Listar servidores\n");
printf("0. Sair do programa\n\n");
printf("> ");
scanf("%c", &input);
fflush(stdin);
switch(input)
{
case '0':
escrever_arquivo(grupo, sizeof(servidor), tamanho);
free(grupo);
printf("Saindo do programa\n");
return 0;
case '1':
if(!tamanho)
{
grupo = malloc(sizeof(servidor));
memoria += sizeof(servidor);
tamanho++;
inserir_servidor(grupo, tamanho);
}
else
{
realloc(grupo, memoria + sizeof(servidor));
memoria += sizeof(servidor);
tamanho++;
inserir_servidor(grupo, tamanho);
}
printf("memoria em uso: %d B , tamanho: %d\n\n", memoria, tamanho);
break;
case '2':
imprimir_servidor(grupo, tamanho);
break;
default:
printf("Inexistente\n");
break;
}
} while(input != '0');
return 0;
}