2013-02-13 15 views
6

लेखक शीर्षक A bus error on my platformअगर cout.rdbuf() का उपयोग बफर को स्विच करने के लिए किया जाता है और उसे कभी सेट नहीं किया जाता है तो क्या गलत हो सकता है?

#include <fstream> 
#include <iostream> 

int main() 
{ 
    std::ofstream log("oops.log"); 
    std::cout.rdbuf(log.rdbuf()); 
    std::cout << "Oops!\n"; 
    return 0; 
} 

स्ट्रिंग "ओह! \ N" फाइल "oops.log" को छापा जाता है के तहत this code प्रस्तुत किया। कोड cout के streambuf को पुनर्स्थापित नहीं करता है, लेकिन VS2010 ने रनटाइम त्रुटि की रिपोर्ट नहीं की है।

+1

आपको अपने शीर्षक पर और विस्तार करना चाहिए। – 0x499602D2

उत्तर

9

log और std::cout शेयर एक बफर के बाद से, कि बफर शायद दो बार मुक्त हो जाएगा (एक बार जब log एक बार फिर दायरे से बाहर चला जाता है, तो जब कार्यक्रम समाप्त हो जाता है)।

इसका परिणाम अपरिभाषित व्यवहार में होता है, इसलिए सटीक कारण बता देना मुश्किल है कि यह उसकी मशीन पर बस त्रुटि क्यों ट्रिगर करता है लेकिन चुपचाप आपके पर विफल रहता है।

+0

मैं आपका उत्तर स्वीकार करूंगा क्योंकि यह मुझे प्राप्त हुआ था। टी.के.एस। –

+0

इस के आसपास पाने के लिए कोई रास्ता? – Caesar

+1

@ कैसर, हां, पहले स्थान पर स्ट्रीम बफर साझा नहीं कर रहा है। मुझे आश्चर्य है कि मूल लेखक ने ऐसा करके क्या हासिल करने की कोशिश की। –

3

आपके कार्यक्रम में व्यवहार को अपरिभाषित किया गया है।

वैश्विक cout ऑब्जेक्ट का विनाश स्कोप से बाहर निकलने पर स्ट्रीम बफर को हटा देगा, और यह log का भी सच है, जो कि उसी स्ट्रीम बफर का भी मालिक है। इस प्रकार, आप एक ही वस्तु को दो बार हटा रहे हैं।

जब किसी प्रोग्राम में अपरिभाषित व्यवहार होता है, तो कुछ भी हो सकता है, आपकी हार्ड ड्राइव को बिना किसी त्रुटि के समाप्त करने के लिए स्वरूपित करने से।

उदाहरण के लिए, प्रोग्राम main() से लौटने के बाद एक अनंत लूप में प्रवेश करता है।

4

चूंकि अन्य उत्तरों का उल्लेख नहीं है कि इसके बारे में क्या करना है, मैं इसे यहां प्रदान करूंगा। आपको बफर को सहेजने और पुनर्स्थापित करने की आवश्यकता है जिसे कोउट को प्रबंधित किया जाना चाहिए। उदाहरण के लिए:

#include <fstream> 
#include <iostream> 

// RAII method of restoring a buffer 
struct buffer_restorer { 
    std::ios &m_s; 
    std::streambuf *m_buf; 

    buffer_restorer(std::ios &s, std::streambuf *buf) : m_s(s), m_buf(buf) {} 
    ~buffer_restorer() { m_s.rdbuf(m_buf); } 
}; 

int main() 
{ 
    std::ofstream log("oops.log"); 
    buffer_restorer r(std::cout, std::cout.rdbuf(log.rdbuf())); 
    std::cout << "Oops!\n"; 
    return 0; 
} 

अब जब cout के बफर से पहले cout कार्यक्रम के अंत में नष्ट हो जाता है बदल दिया जाता है, इसलिए जब cout को नष्ट कर देता है अपने बफ़र सही बात होता है।


बस मानक कब पुनः निर्देशित के लिए आम तौर पर पर्यावरण को पहले से ही करने के लिए है कि आप के लिए की क्षमता है (उदाहरण के लिए खोल में कब पुनर्निर्देशन)। बल्कि उपरोक्त कोड से मैं शायद बस कार्यक्रम चलाने चाहते हैं के रूप में:

yourprogram > oops.log 

इसके अलावा एक बात याद रखना होगा कि std::cout अन्य वैश्विक चर के रूप सभी एक ही कमियां के साथ एक वैश्विक चर रहा है है। इसे संशोधित करने या यहां तक ​​कि इसका उपयोग करने के बजाय आप वैश्विक चर से बचने के लिए सामान्य तकनीकों का उपयोग करना पसंद कर सकते हैं। उदाहरण के लिए आप std::ostream &log_output पैरामीटर पास कर सकते हैं और कोड का उपयोग cout सीधे कोड के बजाय कर सकते हैं।

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

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