Problemas ao armazenar dados dentro uma matriz [RESOLVIDO]

1. Problemas ao armazenar dados dentro uma matriz [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 06/03/2019 - 22:58h




  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 07/03/2019 - 01:53h

Pensando devagar, à medida em que entendo seu código.

Em main(), como você já tem o valor de addrlen após a chamada a accept(), você poderia simplificar tanto realloc_table() quanto a atribuição de endereço usando memset(), as quais, em vez de usar ifs para decidir o tamanho com base no tipo do socket, poderiam se beneficiar do valor já entregue à variável addrlen. Isso ajudaria a facilitar a leitura do código.

Fazendo isso, a preocupação com o tipo do socket ficaria apenas nas funções em que isso é relevante, que são check_addr() e show_addr(). Eu acho realmente que se você diminuir o número de conversões entre tipos de ponteiros diferentes, o programa vai ficar mais fácil de ser entendido e mantido.

Compilando e rodando o seu programa e testando-o a partir de três endereços diferentes (meu IP de LAN, 127.0.0.1 e ::1), o primeiro endereço funciona, e os seguintes, não (mesmo trocando a ordem entre eles). Mais do que isso, rodando o servidor sob o valgrind, ele indica tentativa de ler fora da região de memória alocada em uma chamada a check_addr(). Há portanto, um erro ou na alocação ou no laço de verificação de endereços.

Recompilando o programa com a opção -g, reexecutei-o com o valgrind e vi que ele mostrou que há uma tentativa em check_addr() de acesso a 36 bytes em um objeto que foi alocado com apenas 28 bytes em realloc_table(). 28 bytes é o tamanho de uma struct sockaddr_in6, logo o erro está com certeza em check_addr().


Achei o problema! (E não sei como não o vi antes, sem o valgrind!)

Em check_addr(), você diz primeiro que “addrs6=(struct sockaddr_in6*)buff_addr_table[i];”, logo pega apenas um endereço da tabela. Não obstante, ao chamar memcmp(), você aplica novamente o índice i ao ponteiro addrs6, que se refere a um endereço só. Ali há de se tirar o índice, e dizer apenas “addrs6->sin6_addr.s6_addr”. Problema semelhante ocorre com o teste de IPv4, e tem de ser corrigido também ali.

Aliás, esse é um caso em que o nome da variável atrapalha o diagnóstico. Ao chamá-la de addrs6 (e addrs4), esse “s” dá uma ideia de plural, como se você ainda tivesse um array, quando na verdade já isolou um único endereço. Seria bom, portanto, alterar também o nome da variável.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)





Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts