Come risolvere questo problema bad_alloc?
Domanda
Sto sviluppando un'applicazione che deve interagire tramite FTP. Per questa comunicazione sto attualmente usando C ++, Visual Studio e Poco su Windows.
La seguente riga genera un'eccezione bad_alloc ...
ftp = new FTPClientSession("127.0.0.1", 21);
Quindi sono andato giù e ho provato a inizializzare prima uno StreamSocket, ma fallisce ...
StreamSocket ss = new SocketAddress("127.0.0.1", 21);
Quando vai ancora più in basso, e sembra che il bad_alloc provenga da:
IPAddress * ip = new IPAddress("127.0.0.1");
Quel costruttore contiene: (vedo nel debugger che _pImpl non è inizializzato)
IPAddress::IPAddress(const std::string& addr)
{
_pImpl = IPv4AddressImpl::parse(addr);
if (!_pImpl) throw InvalidAddressException(addr);
}
IPv4AddressImpl :: parse contiene:
static IPv4AddressImpl* parse(const std::string& addr)
{
if (addr.empty()) return 0;
#if defined(_WIN32)
struct in_addr ia;
ia.s_addr = inet_addr(addr.c_str());
if (ia.s_addr == INADDR_NONE && addr != "255.255.255.255")
return 0;
else
return new IPv4AddressImpl(&ia);
#else
#if __GNUC__ < 3
struct in_addr ia;
ia.s_addr = inet_addr(addr.c_str());
if (ia.s_addr == INADDR_NONE && addr != "255.255.255.255")
return 0;
else
return new IPv4AddressImpl(&ia);
#else
struct in_addr ia;
if (inet_aton(addr.c_str(), &ia))
return new IPv4AddressImpl(&ia);
else
return 0;
#endif
#endif
}
Il seguente codice con inet_addr da Winsock2.h (ws2_32.lib) si traduce in "SOMETHING ELSE".
unsigned long ulAddr = INADDR_NONE;
ulAddr = inet_addr("91.183.48.210");
if (ulAddr == INADDR_NONE)
msg("NONE");
else
msg("SOMETHING ELSE");
Non vedo che cosa non va qui ... C'è un modo per eseguire il debug ulteriormente o qualcuno sa cosa non va?
Soluzione
Non sono uno scienziato missilistico ma sembra che dovrai entrare in IPv4AddressImpl ()
con ia.s_addr
popolato con un puntatore alla stringa " 127.0.0.1 "
Appena per interesse, ricevi l'errore quando usi il tuo vero indirizzo IP invece del loopback.
E hai un server FTP in esecuzione su quella macchina?
E sei assolutamente sicuro che la stringa sia " 127.0.0.1 "
?
Aggiornamento:
Ci sono solo tre cose che possono causare l'eccezione.
-
addr.empty ()
è vero, improbabile se addr è" 127.0.0.1 "
. -
is.s_addr
èINADDR_NONE
, ancora una volta improbabile poichéinet_addr ()
non dovrebbe avere problemi con 127.0.0.1 (come hai testato ). - il costruttore per
IPv4AddressImpl ()
restituisce NULL (o genera l'eccezionebad_alloc
).
Quest'ultimo sembra il più probabile, cosa succede quando scrivi il tuo codice per farlo?
struct in_addr ia;
ia.s_addr = inet_addr("127.0.0.1");
IPv4Address *x = new IPv4AddressImpl(&ia);
Inoltre, se si interrompe la riga " if (! _pImpl) butta ... "
ed esamina _pImpl
:
- zero indica che :: parse ha restituito NULL ed è il costruttore
IPAddress ()
che lanciabad_alloc
. - non-zero significa :: lo stesso parse ha generato un'eccezione che potrebbe essere solo dal costruttore
IPv4AddressImpl ()
.
Puoi avere un passo in avanti per eseguire il debug ulteriormente.
Altri suggerimenti
Sembra che l'unica possibile causa sia la chiamata a
inet_addr
sulla linea
ia.s_addr = inet_addr(addr.c_str());
restituisce INADDR_NONE che causa la restituzione di 0 / NULL, causando il lancio dell'eccezione.
Puoi chiamare inet_addr (" 127.0.0.1 ") e vedere quali sono i risultati? Se i risultati sono INADDR_NONE, dovrai trovare un buon indirizzo su inet_addr che renda felice il tuo sistema.
Ecco un link a inet_addr nella documentazione MSDN.
condizioni Stai chiamando il costruttore
IPAddress("127.0.0.1");
con un carattere const *, ma il costruttore accetta riferimenti const
IPAddress::IPAddress(const std::string& str);
il compilatore è abbastanza intelligente da creare quel temporaneo? L'ho provato con VS 2003 e sembra essere ok. Ho il sospetto che la lingua dovrebbe essere abbastanza intelligente da gestirlo, ma ho pensato di segnalarlo.