Invasão de memória de uma string sobre outra string

1. Invasão de memória de uma string sobre outra string

Lucas Veríssimo de Oliveira
donutLukke

(usa Outra)

Enviado em 04/01/2023 - 22:11h

Boa noite pessoal, gostaria da ajuda de vocês.

Estou fazendo um código que pega informações do usuário, coloca em uma AVL e depois passa os dados dessa AVL para um arquivo. O problema é que quando igualo ou sobreponho a quantidade de caracteres da string nome[ ] em relação a string cpf[ ] (ambas da struct "stc_Aluno"), parece haver uma invasão de memória da string nome[ ] em cima da string cpf[ ].

Ao adicionar um aluno, o caminho que o código faz pelas funções é:

char* idAluno(stc_Aluno *a, int opcao);
int compareAluno(stc_Aluno **a, char variavel[ ]);
char* nomeAluno(stc_Aluno *a);
int compareAluno(stc_Aluno **a, char variavel[ ]);
char* cpfAluno(stc_Aluno *a, int opcao);
int compareAluno(stc_Aluno **a, char variavel[ ]);
adicionaAluno(student, aluno.id, aluno.nome, aluno.cpf);
salvarAluno(&student);


Quando uso essa configuração abaixo, o código funciona corretamente, conseguindo detectar que o CPF digitado já existe na lista de dados (imagem 1):

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

#define CAID 10
#define CANOME 11
#define CACPF 12

typedef struct A
{
char id[CAID];
char nome[CANOME];
char cpf[CACPF];
struct A *esquerdo, *direito;
short altura;
}stc_Aluno;


Já quando uso essa configuração abaixo, o código funciona incorretamente, não conseguindo detectar que o CPF digitado existe na lista de dados (imagem 2):

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

#define CAID 10
#define CANOME 12
#define CACPF 12

typedef struct A
{
char id[CAID];
char nome[CANOME];
char cpf[CACPF];
struct A *esquerdo, *direito;
short altura;
}stc_Aluno;


Primeiro o código vai para a função de "idAluno", depois "nomeAluno" e por final a "cpfAluno". Dentro das funções "idAluno" e "cpfAluno", há a função "compareAluno", que é responsável por identificar se o dado digitado já está contido na nossa AVL. No primeiro aluno adicionado, o código roda corretamente, já quando insiro os dados do segundo aluno, no momento da comparação de cpfs, a função ignora se o "cpf" digitado e o "cpf" que está na AVL são iguais.

Vou deixar o link do código logo abaixo, pode fazer a modificação que achar necessária e se possível, coloque aqui nesse post, o que você usou para resolver o problema. https://replit.com/join/snrbwfcatk-lucasverissimo1

Obrigado pela atenção.


  


2. Re: Invasão de memória de uma string sobre outra string

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 04/01/2023 - 22:11h

A resposta a esta questão depende de uma análise minuciosa do código em questão. Possivelmente, o problema pode ser a configuração para a estrutura da struct stc_Aluno. Verifique se as strings nome e cpf possuem o mesmo tamanho configurado, se possível aumente o tamanho da string cpf para que ela seja maior do que a string nome. Da mesma forma, verifique se a função compareAluno está sendo executada corretamente, verifique se as variáveis foram declaradas de forma correta e se os parâmetros definidos são os esperados para esta variável. Tente usar alguns recursos para depuração como o GDB e verifique passo a passo se o código está executando o que você espera.


3. Re: Invasão de memória de uma string sobre outra string

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 05/01/2023 - 00:25h

Não olhei o código todo, mas só pelos tamanhos das strings, já notei que vc esqueceu de adicionar o espaço do caractere nulo.
Por exemplo:
O cpf deve ter 11 chars numéricos, ok, isso é válido, porém, como é uma string em C é preciso colocar +1 char pra poder ser válida.
Então, no caso o CPF deve ter tamanho 12 que é 11 chars válidos do número +1 do caractere nulo. Assim, o último char sempre deve ser adicioionado na posição +1 do cpf.
Verifique os outros dados que também estão na mesma situação.


https://nerdki.blogspot.com/ acessa ai, é grátis
Não gostou? O ícone da casinha é serventia do site!


4. Re: Invasão de memória de uma string sobre outra string

Lucas Veríssimo de Oliveira
donutLukke

(usa Outra)

Enviado em 05/01/2023 - 07:36h


SamL escreveu:

Não olhei o código todo, mas só pelos tamanhos das strings, já notei que vc esqueceu de adicionar o espaço do caractere nulo.
Por exemplo:
O cpf deve ter 11 chars numéricos, ok, isso é válido, porém, como é uma string em C é preciso colocar +1 char pra poder ser válida.
Então, no caso o CPF deve ter tamanho 12 que é 11 chars válidos do número +1 do caractere nulo. Assim, o último char sempre deve ser adicioionado na posição +1 do cpf.
Verifique os outros dados que também estão na mesma situação.


https://nerdki.blogspot.com/ acessa ai, é grátis
Não gostou? O ícone da casinha é serventia do site!


O tamanho do CPF já está em 12.




5. Re: Invasão de memória de uma string sobre outra string

Lucas Veríssimo de Oliveira
donutLukke

(usa Outra)

Enviado em 05/01/2023 - 07:36h


alexabolada escreveu:

A resposta a esta questão depende de uma análise minuciosa do código em questão. Possivelmente, o problema pode ser a configuração para a estrutura da struct stc_Aluno. Verifique se as strings nome e cpf possuem o mesmo tamanho configurado, se possível aumente o tamanho da string cpf para que ela seja maior do que a string nome. Da mesma forma, verifique se a função compareAluno está sendo executada corretamente, verifique se as variáveis foram declaradas de forma correta e se os parâmetros definidos são os esperados para esta variável. Tente usar alguns recursos para depuração como o GDB e verifique passo a passo se o código está executando o que você espera.


Ok, vou tentar isso, obrigado.




6. Re: Invasão de memória de uma string sobre outra string

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 05/01/2023 - 07:36h

Sim, com certeza! A análise do código é fundamental para encontrar e corrigir erros em seu programa. Com bases nessas instruções, você pode usar os recursos de depuração fornecidos pelo GDB para auxiliar: gdb [nome-do-executavel] . Você pode inserir comandos como listar para verificar a linha onde o erro acontece, definir breakpoints para parar a execução do programa em momentos específicos, ou analisar variáveis, entre outros. Para maiores informações, consulte a documentação da plataforma. Boa sorte!"


7. Re: Invasão de memória de uma string sobre outra string

aguamole
aguamole

(usa KUbuntu)

Enviado em 05/01/2023 - 11:44h

A alexabolada esta explicando para você usar o:
https://www.sourceware.org/gdb/
https://pt.wikipedia.org/wiki/GNU_Debugger



8. Re: Invasão de memória de uma string sobre outra string

Paulo
paulo1205

(usa Ubuntu)

Enviado em 05/01/2023 - 13:43h

SamL escreveu:

Não olhei o código todo, mas só pelos tamanhos das strings, já notei que vc esqueceu de adicionar o espaço do caractere nulo.
Por exemplo:
O cpf deve ter 11 chars numéricos, ok, isso é válido, porém, como é uma string em C é preciso colocar +1 char pra poder ser válida.
Então, no caso o CPF deve ter tamanho 12 que é 11 chars válidos do número +1 do caractere nulo. Assim, o último char sempre deve ser adicioionado na posição +1 do cpf.
Verifique os outros dados que também estão na mesma situação.


É possível trabalhar com tamanhos justos de arrays que acomodam texto (estou me policiando para não chamar de strings), desde que toda interação com tais arrays contendo texto sejam feitas por meio de funções específicas, que levem o tamanho justo em consideração. Tal trade-off pode ser interessante para economizar memória ou armazenamento em disco, ao evitar o armazenamento de bytes nulos.

Caso essa configuração de armazenamento justo seja usada, algumas operações típicas têm de ser substituídas. Por exemplo:
// Em lugar de
strcmp(cpf1, cpf2)
// usar
strcmp(cpf1, cpf2, CPFLEN) // CPFLEN provavelmente será uma constante de valor 11.
// Em lugar de
printf("%s", cpf)
// usar
printf("%.*s", CPFLEN, cpf) // Limita a quantidade de caracteres impressos.
// Em lugar de
bool read_cpf(char *cpf){
static char *fmtstr=NULL;
if(!fmtstr)
if(asprintf(&fmtstr, "%%%u[0-9]", CPFLEN)<0)
return false;
return scanf(fmtstr, cpf)==1;
}
// usar
bool read_cpf(char *cpf){
static char *line=NULL;
static size_t linesize=0;
ssize_t linelen=getline(&line, &linesize, stdin);
if(linelen==-1)
return false;
if(linelen>0 && line[linelen-1]=='\n')
line[--linelen]='\0';
if(linelen<=0)
return false;
int n=CPFLEN;
// Copia os dígitos do CPF de trás para a frente.
while(linelen>0)
if(!isdigit(line[--lenlen])
return false; // encontrou caráter inválido
else
cpf[--n]=line[linelen];
// Preenche os dígitos à esquerda com zero.
while(n>0)
cpf[--n]='0';
return true;
}



... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)


9. Re: Invasão de memória de uma string sobre outra string

leandro peçanha scardua
leandropscardua

(usa Ubuntu)

Enviado em 05/01/2023 - 15:32h


Como o prssoal já falou strings em c são srrays de char com um string nulo no final. A função strcmp vai levar isso em consideração(se vc estiver usando) e vai sair percorrendo(e vai ultrapassar) até encontrar a string null. Vc pode testar p ver se é isso inicializando o array c elementos nulos e gravando até a penúltima posição.
Como a @alexabolada sugeriu, rode no gdb (pode ser q já tenha instalado na sua máquina) e rode no debugador. São apenas poucos comandos q vc vai ter de aprender mas vai por mim, vai te poupar muita madrugada doido tentando achar a causa de problema.
Outra coisa é fazer teste automatizado. Vc pode fazer em shell mesmo ou usar um framework como cUnit






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts