whoami-r Posted October 27, 2018 at 01:25 PM Report #612211 Posted October 27, 2018 at 01:25 PM (edited) Boas pessoal, estou a criar uma aplicação servidor-cliente para um trabalho e numa das metas é pedido para utilizar a função getenv(). #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "medit-defaults.h" void dados() { int linhas, colunas, time_out, max_users; linhas=atoi(getenv("MEDIT_MAXLINES")); colunas=atoi(getenv("MEDIT_MAXCOLUMNS")); time_out=atoi(getenv("MEDIT_TIMEOUT")); max_users=atoi(getenv("MEDIT_MAXUSERS")); printf("Linhas: %d\tColunas: %d\t Time_Out:%d\t Max_Users:%d\n",linhas,colunas,time_out,max_users); } void comandos(char *comando) { int i; char *p[2]; *p=strtok(comando," "); if(strcmp(*p,"settings")==0) { dados(); } if(strcmp(*p,"load")==0) { for(i=1;i<2;i++) { *(p+i)=strtok(NULL," "); } printf("Valido.\n"); } if(strcmp(*p,"save")==0) { for(i=1;i<2;i++) { *(p+i)=strtok(NULL," "); } printf("Valido.\n"); } if(strcmp(*p,"free")==0) { for(i=1;i<2;i++) { *(p+i)=strtok(NULL," "); } printf("Valido.\n"); } if(strcmp(*p,"statistics")==0) { printf("Valido.\n"); } if(strcmp(*p,"users")==0) { printf("Valido.\n"); } if(strcmp(*p,"text")==0) { printf("Valido.\n"); } } int main(int argc, char* argv[]) { int n_linhas,n_col; int linhas,colunas; char comando[TAM]; printf("Insira o comando:\n"); scanf("%[^\n]",comando); if(strcmp(comando,"shutdown")==0) { printf("Servidor vai encerrar...\n"); exit(0); } else { comandos(comando); } return 0; } O programa está a funcionar corretamente e de acordo com aquilo que é necessário por agora, mas quando introduzo o comando "settings" aparece-me o erro 'Segmentation fault' e termina Já rodei o programa no windows e não me acontece este erro, gostaria de saber pq é que no linux isto acontece. Para o caso de ajudar melhor a entender o meu problema, deixo também o header file #ifndef MEDITDEFAULTS_H #define MEDITDEFAULTS_H #ifdef __cplusplus extern "C" { #endif #define TAM 50 #define TAM_USER 8 #define MEDIT_MAXCOLUMNS 45 //STRUCT PARA AS CARACTERISTICAS DO UTILIZADOR typedef struct Utilizador { char nome[TAM_USER]; int client_pid; }User; //STRUCT PARA ACOLHER O TEXTO EM EDICAO typedef struct texto_edicao { char linha[MEDIT_MAXCOLUMNS]; char username[TAM_USER]; int client_pid; }Edicao; #ifdef __cplusplus } #endif #endif /* MEDIT_DEFAULTS_H*/ Obrigado Edited October 27, 2018 at 01:27 PM by riqu3s
Rui Carlos Posted October 28, 2018 at 11:08 AM Report #612213 Posted October 28, 2018 at 11:08 AM Não estás a validar o valor devolvido pelo getenv, pelo que corres o risco de chamar a função atoi com NULL, o que resulta num segmentation fault. Começa por colocar o resultado do getenv numa variável, e testa se o mesmo é diferente de NULL antes de chamares o atoi. Rui Carlos Gonçalves
whoami-r Posted October 28, 2018 at 11:21 AM Author Report #612214 Posted October 28, 2018 at 11:21 AM (edited) 23 minutos atrás, Rui Carlos disse: Não estás a validar o valor devolvido pelo getenv, pelo que corres o risco de chamar a função atoi com NULL, o que resulta num segmentation fault. Começa por colocar o resultado do getenv numa variável, e testa se o mesmo é diferente de NULL antes de chamares o atoi. void mostra_dados() { int linhas, colunas, time_out, max_users; char *maxlines = getenv("MEDIT_MAXLINES"); char *maxcolumns = getenv("MEDIT_MAXCOLUMNS"); char *timeout = getenv("MEDIT_TIMEOUT"); char *maxusers = getenv("MEDIT_MAXUSERS"); if(maxlines == NULL || maxcolumns == NULL || timeout == NULL || maxusers == NULL) { printf("Erro de segmentação\n"); exit(0); } else { linhas=atoi(maxlines); colunas=atoi(maxcolumns); time_out=atoi(timeout); max_users=atoi(maxusers); } printf("Linhas: %d\tColunas: %d\t Time_Out:%d\t Max_Users:%d\n",linhas,colunas,time_out,max_users); } Tentei fazer o que disse, mas o que acontece é que me é apresentada a mensagem do printf("Erro de Segmentação") Significa que os getenv() estão a dar NULL, ou pelo menos um deles. Como é que posso contornar isso? Edited October 28, 2018 at 11:31 AM by riqu3s
Rui Carlos Posted October 28, 2018 at 11:31 AM Report #612215 Posted October 28, 2018 at 11:31 AM 11 minutos atrás, riqu3s disse: Tentei fazer o que disse, mas o que acontece é que me é apresentada a mensagem do printf("Erro de Segmentação"); E é isso que estás a dizer à aplicação para fazer quando as variáveis de ambiente não estão definidas, não é? Provavelmente devias mudar a mensagem para algo como "Uma das variáveis de ambiente necessárias para esta operação não está definida. Tente novamente depois de definir todas as variáveis.", visto que não há ali nenhum erro de segmentação, mas sim um erro na utilização do programa. Aquela modificação apenas torna o programa mais robusto, evitando que o mesmo falhe em caso de utilização incorrecta por parte do utilizador. Depois é preciso que o utilizador corrija a forma como chama o programa, definindo as variáveis. Podes mostrar como é que estás a definir as variáveis de ambiente? Rui Carlos Gonçalves
whoami-r Posted October 28, 2018 at 11:44 AM Author Report #612216 Posted October 28, 2018 at 11:44 AM 12 minutos atrás, Rui Carlos disse: E é isso que estás a dizer à aplicação para fazer quando as variáveis de ambiente não estão definidas, não é? Provavelmente devias mudar a mensagem para algo como "Uma das variáveis de ambiente necessárias para esta operação não está definida. Tente novamente depois de definir todas as variáveis.", visto que não há ali nenhum erro de segmentação, mas sim um erro na utilização do programa. Aquela modificação apenas torna o programa mais robusto, evitando que o mesmo falhe em caso de utilização incorrecta por parte do utilizador. Depois é preciso que o utilizador corrija a forma como chama o programa, definindo as variáveis. Podes mostrar como é que estás a definir as variáveis de ambiente? Como é que defino as variáveis de ambiente?
Rui Carlos Posted October 28, 2018 at 12:05 PM Report #612217 Posted October 28, 2018 at 12:05 PM Uma de definires a variável é colocando a definição da mesma antes de cada chamada ao programa (e.g. TESTVAR="value" ./prog), que define a variável (TESTVAR) visível pela aplicação chamada no mesmo comando (prog). Outra é usando o export (e.g. export TESTVAR="value"), que define uma variável visível aos programas chamados futuramente da mesma shell. Rui Carlos Gonçalves
whoami-r Posted October 28, 2018 at 12:13 PM Author Report #612218 Posted October 28, 2018 at 12:13 PM 6 minutos atrás, Rui Carlos disse: Uma de definires a variável é colocando a definição da mesma antes de cada chamada ao programa (e.g. TESTVAR="value" ./prog), que define a variável (TESTVAR) visível pela aplicação chamada no mesmo comando (prog). Outra é usando o export (e.g. export TESTVAR="value"), que define uma variável visível aos programas chamados futuramente da mesma shell. E não há nenhuma forma de definir uma variável no código do programa, de forma a que sempre que o programa é chamado, essas variáveis passam a estar definidas?
Rui Carlos Posted October 28, 2018 at 12:20 PM Report #612219 Posted October 28, 2018 at 12:20 PM 4 minutos atrás, riqu3s disse: E não há nenhuma forma de definir uma variável no código do programa, de forma a que sempre que o programa é chamado, essas variáveis passam a estar definidas? Haver há, mas não faz sentido nenhum. Isso seria o mesmo que ter variáveis globais (com complicações adicionais), que são altamente desaconselhadas. Aquilo que deves fazer é passar as variáveis às funções como parâmetros. Rui Carlos Gonçalves
whoami-r Posted October 28, 2018 at 12:22 PM Author Report #612220 Posted October 28, 2018 at 12:22 PM 2 minutos atrás, Rui Carlos disse: Haver há, mas não faz sentido nenhum. Isso seria o mesmo que ter variáveis globais (com complicações adicionais), que são altamente desaconselhadas. Aquilo que deves fazer é passar as variáveis às funções como parâmetros. Hmm ok, acho que já percebi. Obrigado pela atenção e explicação
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now