Question

I'm developing an application that needs to interact over FTP. For this communication I am currently using C++, Visual Studio and Poco on Windows.

The following line results in a bad_alloc exception...

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

So I went down and tried initializing a StreamSocket first, also fails...

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

When going even further down, and it seems the bad_alloc is coming from:

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

That constructor contains: (I see in the debugger that _pImpl isn't initialised)

IPAddress::IPAddress(const std::string& addr)
{
_pImpl = IPv4AddressImpl::parse(addr);

if (!_pImpl) throw InvalidAddressException(addr);
}

IPv4AddressImpl::parse contains:

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
}

The following code with inet_addr from Winsock2.h (ws2_32.lib) results 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");

I don't see what is going wrong here... Is there a way to debug this further or does someone know what goes wrong?

Was it helpful?

Solution

I'm no rocket scientist but it looks like you'll have to step into IPv4AddressImpl() with ia.s_addr populated with a pointer to the string "127.0.0.1".

Just out of interest, do you get the error when you use your real IP address instead of the loopback.

And, do you have an FTP server running on that machine?

And, are you absolutely certain the string is "127.0.0.1"?

Update:

There's only really three things that can cause the exception.

  • addr.empty() is true, unlikely if addr is "127.0.0.1".
  • is.s_addr is INADDR_NONE, again unlikely since inet_addr() should have no trouble with 127.0.0.1 (as you've tested).
  • the constructor for IPv4AddressImpl() returns NULL (or throws the bad_alloc exception itself).

That last one seems the most likely, what happens when you write your own code to do it?

struct in_addr ia;
ia.s_addr = inet_addr("127.0.0.1");
IPv4Address *x = new IPv4AddressImpl(&ia);

In addition, if you breakpoint on the "if (!_pImpl) throw..." line and examine _pImpl:

  • zero means the ::parse returned NULL and it's the IPAddress() constructor throwing bad_alloc.
  • non-zero means ::parse itself threw an exception which could only be from the IPv4AddressImpl() constructor.

You may have to step into that to debug further.

OTHER TIPS

It looks like the only possible cause is the call to

inet_addr

on the line

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

returns INADDR_NONE which causes 0/NULL to be returned, causing the exception to be thrown.

Can you call inet_addr("127.0.0.1") and see what the results are? If the results are INADDR_NONE, then you'll need to find a good address to inet_addr that makes your system happy.

Here is a link to inet_addr in the MSDN documentation.

Observation You are calling the constructor

 IPAddress("127.0.0.1");

with a const char*, but the constructor takes a const references

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

is the compiler smart enough to create that temporary? I tried it out with VS 2003, and it seems to be ok. I suspect that the language should be smart enough to handle this, but I thought I'd point it out.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top