كيف تحل مشكلة 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");
يحتوي هذا المُنشئ على: (أرى في The Debugger أن _pimpl لم يتم تهيئة)
IPAddress::IPAddress(const std::string& addr)
{
_pImpl = IPv4AddressImpl::parse(addr);
if (!_pImpl) throw InvalidAddressException(addr);
}
IPv4AddressImpl :: يحتوي على:
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()
صحيح ، من غير المحتمل أن يكون Addr"127.0.0.1"
.is.s_addr
هوINADDR_NONE
, ، مرة أخرى غير مرجح منذ ذلك الحينinet_addr()
لا ينبغي أن تواجه أي مشكلة مع 127.0.0.1 (كما اختبرت).- مُنشئ
IPv4AddressImpl()
يعود فارغ (أو يلقي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 عاد فارغة وهو
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*، لكن المُنشئ يأخذ مراجع const
IPAddress::IPAddress(const std::string& str);
هل المترجم ذكي بما يكفي لإنشاء ذلك مؤقت؟ جربته مع VS 2003 ، ويبدو أنه على ما يرام. أظن أن اللغة يجب أن تكون ذكية بما يكفي للتعامل مع هذا ، لكنني اعتقدت أنني سأشير إليها.