चेतावनी! C ++ कार्यान्वयन एसटीडी में खतरनाक बग :: मानचित्र :: मर्ज और एसटीडी :: सेट :: दृश्य स्टूडियो 2017 में विलय

यदि आप MS Visual Studio 2017 में C ++ 17 मानक का उपयोग करते हैं - तो सावधान रहें: वर्तमान संस्करण में std :: map :: merge और std :: set :: merge के कार्यान्वयन में एक महत्वपूर्ण बग है। विवरण - कटौती के तहत।

बग कैसे प्रकट होता है?


  1. एसटीडी की जटिलता :: नक्शा :: मर्ज और एसटीडी :: सेट :: मानक एन * लॉग (आकार () + एन) के बजाय मर्ज करें, जहां एन जोड़ा गया भाग का आकार है, एन स्क्वार्ड के बारे में पता चला है।
  2. यदि पर्याप्त मात्रा में तत्वों के साथ एक कंटेनर को मर्ज की मदद से जोड़ा गया था, तो परिणामस्वरूप कंटेनर के विनाश पर हमें ढेर अतिप्रवाह मिलता है।
  3. मर्ज चलने के बाद कंटेनर गलत स्थिति में आता है, इसलिए अन्य अभिव्यक्तियां संभव हैं।

Microsoft क्या कहता है?


यह बग्रेपोर्ट मेरे द्वारा लगभग 2 महीने पहले Microsoft को भेजा गया था।
Visual Studio 2019 में अद्यतन 2 पूर्वावलोकन 2 को ठीक किया जाना चाहिए था।

लेकिन विजुअल स्टूडियो 2017 के वर्तमान संस्करण में 15.9.12 को अभी तक तय नहीं किया गया है, और नवीनतम रिपोर्टों को देखते हुए, एक लंबी प्रतीक्षा करें ...

बग लाल-आबनूस के कार्यान्वयन में जोड़ा गया नोड्स का गलत रंग अंकन है।

प्रजनन कैसे करें?


//#include "pch.h" #include <chrono> #include <string> #include <iostream> #include <map> #include <set> const size_t mainSize = 50'000; const size_t additionSize = mainSize; auto getMainMap() { std::map<size_t, std::string> result; while( result.size() < mainSize ) result.emplace(result.size(), "SomeText"); return result; } auto getAdditionMap() { std::map<size_t, std::string> result; while ( result.size() < additionSize ) result.emplace(mainSize + result.size(), "SomeAdditionText"); return result; } int main() { { auto mainMap = getMainMap(); auto addition = getAdditionMap(); auto start = std::chrono::steady_clock::now(); for ( auto const &elem : addition ) mainMap.emplace(elem); auto end = std::chrono::steady_clock::now(); std::cout << "manual insertion with copy: " << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << std::endl; } { auto mainMap = getMainMap(); auto addition = getAdditionMap(); auto start = std::chrono::steady_clock::now(); mainMap.merge(addition); auto end = std::chrono::steady_clock::now(); std::cout << "std::map::merge: " << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << std::endl; } // <---- and stack overflow here because of incorrect mainMap after merge return 0; } 

मेनसाइज़ के मूल्य को भिन्न करते हुए, आप अलग-अलग परिणाम प्राप्त कर सकते हैं - या तो केवल धीमी गति से निष्पादन, या दुर्घटना भी।

क्या करें?


अपना कोड संशोधित करें और मैन्युअल सम्मिलन के साथ मर्ज कॉल बदलें। या VS 2019 में अपग्रेड करें।
और अगर संकलित कोड पहले ही ग्राहक के पास चला गया है ... ओह ...

Source: https://habr.com/ru/post/hi455632/


All Articles