डेढ़ महीने पहले पार्टी के लिए देर से होने के लिए किसी और ने माफ़ी मांगी। ओह ठीक है, मैं सॉफ्टवेयर पुरातत्व करने में काफी समय बिताता हूं।
मुझे दिलचस्पी है कि किसी ने भी मूल डिज़ाइन में स्मृति रिसाव या ऑफ-बाय-वन त्रुटि में स्पष्ट रूप से टिप्पणी नहीं की है। और यह मेमोरी लीक देख रहा था जो मुझे बताता है कि आपको डबल-फ्री त्रुटि क्यों मिल रही है (क्योंकि, सटीक होने के लिए, आप एक ही मेमोरी को कई बार मुक्त कर रहे हैं - और आप पहले से ही मुक्त स्मृति पर ट्रामलिंग के बाद ऐसा कर रहे हैं)।
विश्लेषण करने से पहले, मैं उन लोगों से सहमत हूं जो कहते हैं कि आपका इंटरफ़ेस तारकीय से कम है; हालांकि, अगर आपने मेमोरी रिसाव / ट्रामप्लिंग मुद्दों के साथ निपटाया है और 'आवंटित स्मृति आवंटित' की आवश्यकता है, तो यह 'ठीक' हो सकता है।
क्या समस्याएं हैं? खैर, आप realloc (), और realloc() को बफर पास करते हैं, आपको उस क्षेत्र में एक नया सूचक देता है जिसका उपयोग आप करना चाहिए - और आप उस वापसी मान को अनदेखा करते हैं। नतीजतन, realloc() शायद मूल स्मृति को मुक्त कर दिया है, और फिर आप इसे एक ही सूचक को फिर से पास कर देते हैं, और यह शिकायत करता है कि आप एक ही स्मृति को दो बार मुक्त कर रहे हैं क्योंकि आप इसे मूल मान फिर से पास करते हैं। यह न केवल स्मृति को रिसाव करता है, बल्कि इसका मतलब है कि आप मूल स्थान का उपयोग जारी रखते हैं - और जॉन डाउनी के अंधेरे बिंदुओं में गोली मार दी गई है कि आप realloc() का दुरुपयोग कर रहे हैं, लेकिन इस बात पर जोर नहीं देते कि आप ऐसा कितना गंभीर कर रहे हैं। एक-एक-एक त्रुटि भी है क्योंकि आप स्ट्रिंग को समाप्त करने वाले NUL '\ 0' के लिए पर्याप्त स्थान आवंटित नहीं करते हैं।
स्मृति रिसाव तब होता है क्योंकि आप कॉलर को स्ट्रिंग के अंतिम मान के बारे में बताने के लिए एक तंत्र प्रदान नहीं करते हैं। चूंकि आपने मूल स्ट्रिंग और इसके बाद की जगह पर ट्रैम्पलिंग रखा है, ऐसा लगता है कि कोड काम करता है, लेकिन यदि आपका कॉलिंग कोड अंतरिक्ष को मुक्त करता है, तो उसे भी डबल-फ्री त्रुटि मिल जाएगी, या इसे कोर डंप या समकक्ष मिल सकता है क्योंकि स्मृति नियंत्रण जानकारी पूरी तरह से scrambled है।
आपका कोड अनिश्चितकालीन विकास के खिलाफ भी सुरक्षा नहीं करता है - 'जॉयएक्स नोएल' के साथ 'नोएल' को बदलने पर विचार करें। हर बार, आप 7 अक्षर जोड़ देंगे, लेकिन आपको प्रतिस्थापित टेक्स्ट में एक और नोएल मिलेगा, और इसे विस्तारित किया जाएगा, और इसी तरह आगे। मेरा फिक्सअप (नीचे) इस समस्या को संबोधित नहीं करता है - सरल समाधान शायद यह जांचने के लिए है कि खोज स्ट्रिंग प्रतिस्थापन स्ट्रिंग में दिखाई देती है या नहीं; एक विकल्प प्रतिस्थापन स्ट्रिंग को छोड़ना है और इसके बाद खोज जारी रखना है। दूसरे में पते के लिए कुछ गैर-मामूली कोडिंग समस्याएं हैं।
तो, आपके बुलाए गए फ़ंक्शन का मेरा सुझाया गया संशोधन है:
char *strrep(char *input, char *search, char *replace) {
int searchLen = strlen(search);
int replaceLen = strlen(replace);
int delta = replaceLen - searchLen;
char *find = input;
while ((find = strstr(find, search)) != 0) {
if (delta > 0) {
input = realloc(input, strlen(input) + delta + 1);
find = strstr(input, search);
}
memmove(find + replaceLen, find + searchLen, strlen(input) + 1 - (find - input));
memmove(find, replace, replaceLen);
}
return(input);
}
यह कोड स्मृति आवंटन त्रुटियों का पता नहीं लगाता है - और संभवतः क्रैश (लेकिन यदि नहीं, स्मृति को लीक करता है) यदि realloc() विफल रहता है। स्मृति प्रबंधन मुद्दों की व्यापक चर्चा के लिए स्टीव Maguire के 'लेखन ठोस कोड' पुस्तक देखें।