Как решить эту проблему bad_alloc?
Вопрос
Я разрабатываю приложение, которое должно взаимодействовать через FTP.Для этого общения я сейчас использую C++, Visual Studio и Poco в Windows.
Следующая строка приводит к исключению bad_alloc...
ftp = new FTPClientSession("127.0.0.1", 21);
Итак, я спустился и попытался сначала инициализировать StreamSocket, но тоже не получилось...
StreamSocket ss = new SocketAddress("127.0.0.1", 21);
Если идти еще дальше, кажется, что bad_alloc исходит от:
IPAddress * ip = new IPAddress("127.0.0.1");
Этот конструктор содержит:(В отладчике я вижу, что _pImpl не инициализирован)
IPAddress::IPAddress(const std::string& addr)
{
_pImpl = IPv4AddressImpl::parse(addr);
if (!_pImpl) throw InvalidAddressException(addr);
}
IPv4AddressImpl::parse содержит:
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
}
Следующий код с inet_addr из Winsock2.h (ws2_32.lib) приводит к «ЧТО-ТО ДРУГОМ».
unsigned long ulAddr = INADDR_NONE;
ulAddr = inet_addr("91.183.48.210");
if (ulAddr == INADDR_NONE)
msg("NONE");
else
msg("SOMETHING ELSE");
Я не вижу, что здесь не так...Есть ли способ отладить это дальше или кто-нибудь знает, что пошло не так?
Решение
Я не ракетостроитель, но, похоже, вам придется вступить в IPv4AddressImpl()
с ia.s_addr
заполнен указателем на строку "127.0.0.1"
.
Просто ради интереса, вы получаете ошибку, когда используете свой реальный IP-адрес вместо обратной связи.
И есть ли у вас FTP-сервер на этом компьютере?
И ты абсолютно уверен, что строка "127.0.0.1"
?
Обновлять:
На самом деле есть только три вещи, которые могут вызвать исключение.
addr.empty()
верно, маловероятно, если адрес равен"127.0.0.1"
.is.s_addr
являетсяINADDR_NONE
, опять же маловероятно, посколькуinet_addr()
не должно возникнуть проблем с 127.0.0.1 (как вы тестировали).- конструктор для
IPv4AddressImpl()
возвращает NULL (или выбрасываетbad_alloc
само исключение).
Последний вариант кажется наиболее вероятным. Что произойдет, если вы напишете для этого собственный код?
struct in_addr ia;
ia.s_addr = inet_addr("127.0.0.1");
IPv4Address *x = new IPv4AddressImpl(&ia);
Кроме того, если вы установите точку останова на "if (!_pImpl) throw..."
линия и осмотр _pImpl
:
- ноль означает, что ::parse вернул NULL, и это
IPAddress()
конструктор бросаниеbad_alloc
. - ненулевое значение означает, что ::parse сам выдал исключение, которое могло быть только из
IPv4AddressImpl()
конструктор.
Вы можете иметь вступить в это для дальнейшей отладки.
Другие советы
Похоже, что единственной возможной причиной является вызов
inet_addr
на линии
ia.s_addr = inet_addr(addr.c_str());
возвращает INADDR_NONE, что приводит к возврату 0/NULL, что приводит к выдаче исключения.
Можете ли вы вызвать inet_addr("127.0.0.1") и посмотреть, каковы результаты?Если результат INADDR_NONE, вам нужно найти хороший адрес inet_addr, который сделает вашу систему счастливой.
Вот ссылка на inet_addr в документации MSDN.
НаблюдениеВы вызываете конструктор
IPAddress("127.0.0.1");
с const char*, но конструктор принимает константные ссылки
IPAddress::IPAddress(const std::string& str);
достаточно ли умен компилятор, чтобы создать это временно?Я попробовал это с VS 2003, и вроде все в порядке.Я подозреваю, что язык должен быть достаточно умным, чтобы справиться с этим, но я решил указать на это.