Comment résoudre ce problème bad_alloc?
Question
Je développe une application devant pouvoir interagir via FTP. Pour cette communication, j'utilise actuellement C ++, Visual Studio et Poco sous Windows.
La ligne suivante génère une exception bad_alloc ...
ftp = new FTPClientSession("127.0.0.1", 21);
Je suis donc descendu et j'ai d'abord essayé d'initialiser StreamSocket, mais cela échoue également ...
StreamSocket ss = new SocketAddress("127.0.0.1", 21);
Si vous descendez encore plus bas, il semble que bad_alloc vienne de:
IPAddress * ip = new IPAddress("127.0.0.1");
Ce constructeur contient: (je vois dans le débogueur que _pImpl n'est pas initialisé)
IPAddress::IPAddress(const std::string& addr)
{
_pImpl = IPv4AddressImpl::parse(addr);
if (!_pImpl) throw InvalidAddressException(addr);
}
IPv4AddressImpl :: parse contient:
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
}
Le code suivant avec inet_addr à partir de Winsock2.h (ws2_32.lib) génère "QUELQUE CHOSE D'AUTRE".
unsigned long ulAddr = INADDR_NONE;
ulAddr = inet_addr("91.183.48.210");
if (ulAddr == INADDR_NONE)
msg("NONE");
else
msg("SOMETHING ELSE");
Je ne vois pas ce qui ne va pas ici ... Y a-t-il un moyen de déboguer cette question ou quelqu'un sait-il ce qui ne va pas?
La solution
Je ne suis pas un scientifique confirmé, mais il semblerait que vous deviez entrer dans IPv4AddressImpl ()
avec ia.s_addr
rempli d'un pointeur sur la chaîne "127.0.0.1"
.
Juste par intérêt, obtenez-vous l'erreur lorsque vous utilisez votre adresse IP réelle au lieu du bouclage.
Et avez-vous un serveur FTP en cours d'exécution sur cette machine?
Et êtes-vous absolument certain que la chaîne est "127.0.0.1"
?
Mise à jour:
Il n'y a vraiment que trois choses qui peuvent causer l'exception.
-
addr.empty ()
est vrai, peu probable si addr est"127.0.0.1"
. -
is.s_addr
estINADDR_NONE
, encore une fois peu probable, carinet_addr ()
ne devrait rencontrer aucun problème avec 127.0.0.1 (comme vous l'avez testé). ). - le constructeur de
IPv4AddressImpl ()
renvoie NULL (ou lève l'exceptionbad_alloc
elle-même).
Ce dernier semble le plus probable. Que se passe-t-il lorsque vous écrivez votre propre code pour le faire?
struct in_addr ia;
ia.s_addr = inet_addr("127.0.0.1");
IPv4Address *x = new IPv4AddressImpl(&ia);
De plus, si vous définissez un point d'arrêt sur la ligne "si (! _pImpl) lance ..."
, examinez _pImpl
:
- zéro signifie que le :: parse a renvoyé la valeur NULL et qu'il s'agit du constructeur
IPAddress ()
qui renvoiebad_alloc
. - des moyens non nuls: :: Parse a lui-même lancé une exception qui ne peut provenir que du constructeur
IPv4AddressImpl ()
.
Vous pouvez devoir y accéder pour déboguer plus avant.
Autres conseils
Il semble que la seule cause possible soit l'appel à
inet_addr
sur la ligne
ia.s_addr = inet_addr(addr.c_str());
renvoie INADDR_NONE, ce qui entraîne le renvoi de 0 / NULL et la levée de l'exception.
Pouvez-vous appeler inet_addr ("127.0.0.1") et voir quels sont les résultats? Si les résultats sont INADDR_NONE, vous devez trouver une bonne adresse pour inet_addr qui rend votre système heureux.
Voici un lien vers inet_addr . dans la documentation MSDN.
Observation Vous appelez le constructeur
IPAddress("127.0.0.1");
avec un caractère const *, mais le constructeur prend une référence const
IPAddress::IPAddress(const std::string& str);
Le compilateur est-il assez intelligent pour créer ce temporaire? Je l'ai essayé avec VS 2003, et ça semble aller. Je pense que le langage devrait être assez intelligent pour gérer cela, mais je pensais le préciser.