PDA

View Full Version : [c/c++] strano problema di allocazione memoria su linux


mamo139
21-04-2011, 12:29
server::server(){
port = 0;
serverup = 0;
loaded = 0;
logfile = (char *) malloc(SERVER_PATHS_SIZE*sizeof(char));
}

int server::load(int in_id, char *in_name, char *in_ip, int in_port,
char *in_rcon, char *in_logfile){

int err;

sprintf(name, "%s\x00", in_name);
sprintf(ip, "%s\x00", in_ip);
port = in_port;
sprintf(rcon, "%s\x00", in_rcon);
sprintf(logfile,"%s\x00", in_logfile);

err = urt.set(ip, port, rcon);
if(err < 1){
printf("server::load(): error from urt.set()\n");
return 0;
}

printf("server::load(): server %d loaded!\n", id);
loaded = 1;

return 1;
}



ho segnato in rosso le due righe che mi danno problemi.
alla seconda riga in rosso arriva un bel (anzi brutto :( ) segmentation fault, come se non avessi allocato memoria per l'array logfile. Infatti se alloco la memoria nella stessa funzione il problema non si presenta.

E' come se la memoria venisse rilasciata alla fine di ogni funzione e non mi desse la possibilità di tenerla allocata fino a quando non chiamo free o il programma non termina.
cosa puo essere?
su windows non mi è mai capitato ed è la mia prima volta che programmo su linux e ho sto problema!

grazie mille :)

tuccio`
21-04-2011, 12:59
può essere che la lunghezza di in_logfile sia maggiore di quella allocata? o che manchi il terminatore in quella stringa? magari puoi usare


strncpy(logfile, in_logfile, SERVER_PATHS_SIZE - 1);


per essere sicuro di non andare oltre

ps: tutto questo supponendo che la malloc ritorni un valore != NULL, cosa che però non controlli

sottovento
21-04-2011, 14:26
ho segnato in rosso le due righe che mi danno problemi.
alla seconda riga in rosso arriva un bel (anzi brutto :( ) segmentation fault, come se non avessi allocato memoria per l'array logfile. Infatti se alloco la memoria nella stessa funzione il problema non si presenta.

E' come se la memoria venisse rilasciata alla fine di ogni funzione e non mi desse la possibilità di tenerla allocata fino a quando non chiamo free o il programma non termina.
cosa puo essere?
su windows non mi è mai capitato ed è la mia prima volta che programmo su linux e ho sto problema!

grazie mille :)

Quando si alloca la memoria, si deve controllare il valore di ritorno, se la memoria e' stata effettivamente allocata, altrimenti si commette errore di "blind faith" (fede cieca).

Una volta che il controllo e' stato aggiunto e quindi si e' sicuri che la memoria e' effettivamente allocata (se non e' allocata, allora hai trovato il problema che era nascosto dalla blind faith) e si ha il crash, si puo' stampare l'indirizzo di memoria allocato. Deve ovviamente coincidere con quello allocato, altrimenti hai una seconda dichiarazione da qualche altra parte. Fermo restando, ovviamente, quanto detto da tuccio

WarDuck
21-04-2011, 14:42
Quando si alloca la memoria, si deve controllare il valore di ritorno, se la memoria e' stata effettivamente allocata, altrimenti si commette errore di "blind faith" (fede cieca).

Una volta che il controllo e' stato aggiunto e quindi si e' sicuri che la memoria e' effettivamente allocata (se non e' allocata, allora hai trovato il problema che era nascosto dalla blind faith) e si ha il crash, si puo' stampare l'indirizzo di memoria allocato. Deve ovviamente coincidere con quello allocato, altrimenti hai una seconda dichiarazione da qualche altra parte. Fermo restando, ovviamente, quanto detto da tuccio

Relativamente a questo, secondo me conviene crearsi una funzione che chiama malloc e testa il valore ritornato ;).


void* custom_alloc(size_t size)
{
void* ptr = malloc(size);

if (!ptr)
{
printf("%s\n", "bad allocation");
exit(-1);
}

return ptr;
}


Credo si possa usare anche qualche variabile definita dal compilatore per farsi ritornare la riga alla quale si è usciti.

Che poi se si utilizza C++ forse è meglio usare l'operatore new.

Comunque dando una rapida occhiata al codice vedo che usi sprintf, questo è un problema perché se la stringa di partenza non ha il terminatore sono guai ed inoltre puoi sforare, ti conviene usare snprintf almeno sai quanto scrivi ;).

mamo139
21-04-2011, 15:30
Ok ho risolto il problema rivisitando il modo in cui avevo dichiarato la classe.
Infatti avevo solo allocato con malloc lo spazio per un puntatore alla classe "server". Quindi probabilmente non è mai stato chiamato il costruttore! :p

Grazie a tutti per le risposte, comunque quello che mi avete scritto mi è stato utile per imparare qualcosa in piu.