0

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?

Tamara Wijsman
  • 12,198
  • 8
  • 53
  • 82
  • When you say "_pimpl is not initialised" do you mean it is assigned the value zero in the IPAddress constructor? –  Apr 30 '09 at 13:49
  • ip = 0xcccccc { _pImpl = ??? } CXX0076: Error: – Tamara Wijsman Apr 30 '09 at 14:02
  • It's unable to evaluate the expression of _pImpl, thus probably not initialised. – Tamara Wijsman Apr 30 '09 at 14:03
  • If that's the value of ip, then it's not the case that _pImpl is uninitialized. The problem is that ip itself is uninitialized. You're looking at the garbage value that ip began life with. If you're still in the constructor, then the "new" expression hasn't finished running yet, and so the assignment to ip hasn't happened. Don't say "ip" when you really want "this." – Rob Kennedy Apr 30 '09 at 14:08
  • Hehe, indeed... Details mather. – Tamara Wijsman Apr 30 '09 at 14:17

2 Answers2

1

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.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Because these are compiled libraries I can't step into the code. Whatever IP I try (over the internet, a domain name or local), they all result in the same. And yes, there is a FTP server running on both my PC and the server over the internet. This actually doesnt' mather for IPAddress. – Tamara Wijsman Apr 30 '09 at 13:56
  • No, the FTP server was a long shot. But if you can view the source, why can you not recompile in debug mode to step into it? – paxdiablo Apr 30 '09 at 13:59
0

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.

Doug T.
  • 64,223
  • 27
  • 138
  • 202