2016-08-17 4 views
22

निम्नलिखित कार्यक्रम पर विचार करें के बीच में फेंक:स्मृति रिसाव जीसीसी (लेकिन नहीं बजना) के तहत जब एसटीडी के लिए एक सी ++ 14 प्रारंभकर्ता सूची :: सूची <shared_ptr>

#include <stdexcept> 
#include <stdio.h> 
#include <memory> 
#include <list> 
class Foo { 
public: 
    Foo(){ 
     if (s_ct==0) {throw std::bad_alloc();} 
     --s_ct; 
     fprintf(stderr, "ctor %p\n", this); 
    } 
    ~Foo(){ 
     fprintf(stderr, "dtor %p\n", this); 
    } 
private: 
    static int s_ct; 
}; 

int Foo::s_ct = 2; 

int main(){ 
    try { 
     std::list<std::shared_ptr<Foo>> l = { 
      std::make_shared<Foo>(), 
      std::make_shared<Foo>(), 
      std::make_shared<Foo>() 
     }; 
    } catch (std::bad_alloc&) { 
     fprintf(stderr, "caught exception.\n"); 
    } 
    fprintf(stderr, "done.\n"); 
    return 0; 
} 

इस तरह संकलित:

[little:~] $ g++ --version 
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609 
Copyright (C) 2015 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. 

[little:~] $ g++ --std=c++14 -o list_init list_init.cc 
[little:~] $ 

उत्पादन होता है:

[little:~] $ ./list_init 
ctor 0x1294c30 
ctor 0x1294c50 
caught exception. 
done. 
[little:~] $ 

सूचना है कि विनाशकर्ता कहा जाता है नहीं कर रहे हैं। वाल्ग्रिंड अच्छी तरह से रिसाव की शिकायत भी करता है।

यह std::make_shared के मुख्य उद्देश्यों में से एक का उल्लंघन करता है - अर्थात्, यदि कथन में एक और अभिव्यक्ति फेंकता है, तो साझा ऑब्जेक्ट ठीक से नष्ट हो जाता है क्योंकि यह पूरी तरह से निर्मित साझा पॉइंटर ऑब्जेक्ट द्वारा लपेटा जाता है।

बजना करता है मैं यहाँ क्या पसंद करेंगे:

[little:~] $ clang++ --version 
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final) 
Target: x86_64-pc-linux-gnu 
Thread model: posix 
InstalledDir: /usr/bin 
[little:~] $ clang++ --std=c++14 -o foo list_init.cc 
[little:~] $ ./foo 
ctor 0x1dfec30 
ctor 0x1dfec50 
dtor 0x1dfec50 
dtor 0x1dfec30 
caught exception. 
done. 
[little:~] $ 

तो यह एक जीसीसी बग है, या मैं अपने कार्यक्रम तय करने के लिए की जरूरत है?

+16

एक [gcc bug] (https://gcc.gnu.org/ml/gcc-bugs/2015-05/msg01091.html) जैसा दिखता है: * "आंशिक रूप से निर्मित अज्ञात संरचना/सरणी के सदस्यों के लिए विनाशक नहीं कहा जाता है "*। –

उत्तर

12

मेरी टिप्पणी को एक उत्तर में बदलना ताकि आप प्रश्न के उत्तर के रूप में चिह्नित कर सकें। नाशक आंशिक रूप से निर्माण किया गुमनाम struct के सदस्यों के लिए नहीं बुलाया/सरणी विशेष पिछले दो टेस्ट केस जो प्रयोग में

नोट -

यह एक जीसीसी बग

Bug 66139 होने के लिए लग रहा है समस्या का वर्णन करने के लिए std::initializer_list

+0

क्या यह आंशिक वस्तुओं से अलग है (बनाया गया है अगर निर्माता से अपवाद फेंक दिया गया हो) और विनाशक को बाद में नहीं बुलाया जाएगा –

संबंधित मुद्दे