2009-04-30 9 views
0

Je développe une application qui doit interagir sur FTP. Pour cette communication, j'utilise actuellement C++, Visual Studio et Poco sous Windows.Comment résoudre ce problème bad_alloc?

Les résultats de la ligne suivante dans une exception bad_alloc ...

ftp = new FTPClientSession("127.0.0.1", 21); 

Je suis donc allé et essayé l'initialisation d'un premier StreamSocket, échoue aussi ...

StreamSocket ss = new SocketAddress("127.0.0.1", 21); 

Lorsque vous allez encore plus loin , et il semble que le bad_alloc provient:

IPAddress * ip = new IPAddress("127.0.0.1"); 

Ce constructeur contient: (I voir dans le débogueur que _pImpl n'est pas initialisés)

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 de WINSOCK2.H (Ws2_32.lib) résultats dans « AUTRE CHOSE ". Je ne vois pas ce qui ne va pas ici ... Y a-t-il un moyen de déboguer davantage ou quelqu'un sait-il ce qui ne va pas?

+0

Lorsque vous dites "_pimpl n'est pas initialisé", voulez-vous dire que la valeur zéro est affectée au constructeur IPAddress? –

+0

ip = 0xcccccc {_pImpl = ??? } CXX0076: Erreur: –

+0

Il est impossible d'évaluer l'expression de _pImpl, donc probablement pas initialisée. –

Répondre

1

Je ne suis pas un spécialiste des fusées mais il semblerait que vous deviez entrer dans IPv4AddressImpl() avec ia.s_addr rempli avec un pointeur vers 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 fonctionnant sur cette machine?

Et, êtes-vous absolument certain que la chaîne est "127.0.0.1"?

Mise à jour:

Il n'y a que trois vraiment des choses qui peuvent faire en sorte que l'exception.

  • addr.empty() est vrai, peu probable si addr est "127.0.0.1".
  • is.s_addr est INADDR_NONE, encore une fois peu probable puisque inet_addr() ne devrait avoir aucun problème avec 127.0.0.1 (comme vous l'avez testé).
  • le constructeur pour IPv4AddressImpl() renvoie NULL (ou déclenche l'exception bad_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); 

En outre, si vous le point d'arrêt sur la ligne "if (!_pImpl) throw..." et examiniez _pImpl:

  • zéro signifie que le :: parse retourné NULL et il est le constructeur IPAddress() lancer bad_alloc.
  • non nul signifie que :: parse lui-même a lancé une exception qui ne pouvait provenir que du constructeur IPv4AddressImpl().

Vous pouvez avoir pour avancer dans ce déboguer plus loin.

+0

Parce que ce sont des bibliothèques compilées je ne peux pas entrer dans le code. Quelle que soit l'adresse IP que j'essaie (via Internet, un nom de domaine ou un nom de domaine), tous aboutissent au même résultat. Et oui, il y a un serveur FTP fonctionnant sur mon PC et le serveur sur Internet. Ce n'est pas le cas pour IPAddress. –

+0

Non, le serveur FTP était long. Mais si vous pouvez voir la source, pourquoi ne pouvez-vous pas la recompiler en mode débogage pour y accéder? – paxdiablo

+0

Le problème était que je n'obtiens pas ce problème en mode debug, bizarre ... –

0

Il semble que la seule cause possible est l'appel à

inet_addr 

sur la ligne

ia.s_addr = inet_addr(addr.c_str()); 

retours INADDR_NONE qui provoque 0/NULL à retourner, ce qui provoque l'exception à être jeté.

Pouvez-vous appeler inet_addr ("127.0.0.1") et voir quels sont les résultats? Si les résultats sont INADDR_NONE, vous devrez trouver une bonne adresse pour inet_addr qui satisfera votre système.

Voici un lien vers inet_addr dans la documentation MSDN.

Observation Vous appelez le constructeur

IPAddress("127.0.0.1"); 

avec un const char *, mais le constructeur prend une const référence

IPAddress::IPAddress(const std::string& str); 

est le compilateur assez intelligent pour créer ce temporaire? Je l'ai essayé avec VS 2003, et ça semble aller. Je soupçonne que le langage devrait être assez intelligent pour gérer cela, mais j'ai pensé que je le ferais remarquer.

+0

C'était ma première pensée mais inet_addr est une fonction très simple et ne devrait pas avoir de problème avec "127.0.0.1". – paxdiablo

+0

WinSock2.h, ws2_32.lib, inet_addr donne en effet une bonne adresse. –

+0

En ce qui concerne la conversion à une référence, oui le compilateur est assez intelligent - c'est un idiome très commun en C++. –

Questions connexes