नहीं, मुझे नहीं लगता कि ऐसी चीज हो सकती है। स्ट्रिंग वैरिएबल के लिए एक ऐसा मान प्राप्त करना संभव है जिसकी आपने अपेक्षा नहीं की थी, लेकिन यह स्मृति को रिसाव नहीं करेगा। इस पर विचार करें:
var
Global: string;
procedure One(const Arg: string);
begin
Global := '';
// Oops. This is an invalid reference now. Arg points to
// what Global used to refer to, which isn't there anymore.
writeln(Arg);
end;
procedure Two;
begin
Global := 'foo';
UniqueString(Global);
One(Global);
Assert(Global = 'foo', 'Uh-oh. The argument isn''t really const?');
end;
यहाँ One
तर्क स्थिरांक घोषित किया जाता है, तो माना जाता है कि, यह नहीं बदलेगा। लेकिन फिर One
circumvents कि औपचारिक पैरामीटर के बजाय वास्तविक पैरामीटर को बदलकर। प्रक्रिया Two
"जानता है" कि One
का तर्क स्थिर है, इसलिए यह वास्तविक पैरामीटर को अपने मूल मान को बनाए रखने की अपेक्षा करता है। दावा विफल रहता है।
स्ट्रिंग लीक नहीं हुई है, लेकिन यह कोड दर्शाता है कि आप एक स्ट्रिंग के लिए संदर्भ को कैसे हल कर सकते हैं। Arg
Global
का स्थानीय उपनाम है। यद्यपि हमने Global
बदल दिया है, Arg
का मान छूटा हुआ है, और क्योंकि इसे कॉन्स्ट घोषित किया गया था, इसलिए स्ट्रिंग की संदर्भ संख्या फ़ंक्शन में प्रवेश पर वृद्धि नहीं हुई थी। Global
को पुन: असाइन करना संदर्भ संख्या को शून्य पर गिरा दिया गया, और स्ट्रिंग नष्ट हो गई। Var के रूप में Arg
घोषित करना एक ही समस्या होगी; मूल्य से गुजरने से यह समस्या ठीक हो जाएगी। (UniqueString
पर कॉल यह सुनिश्चित करने के लिए है कि स्ट्रिंग संदर्भ-गणना की गई है। अन्यथा, यह एक गैर-संदर्भ-गिनती स्ट्रिंग अक्षर हो सकता है।) सभी कंपाइलर-प्रबंधित प्रकार इस समस्या के लिए अतिसंवेदनशील हैं; सरल प्रकार प्रतिरक्षा हैं।
स्ट्रिंग को रिसाव करने का एकमात्र तरीका यह है कि इसे स्ट्रिंग के अलावा किसी अन्य चीज़ के रूप में या गैर-प्रकार-जागरूक स्मृति-प्रबंधन कार्यों का उपयोग करना है।Mghie's answer वर्णन करता है कि एक स्ट्रिंग वैरिएबल को क्लॉबर करने के लिए FillChar
का उपयोग कर स्ट्रिंग के अलावा किसी अन्य स्ट्रिंग का इलाज कैसे करें। गैर-प्रकार-जागरूक स्मृति कार्यों में GetMem
और FreeMem
शामिल हैं। उदाहरण के लिए:
type
PRec = ^TRec;
TRec = record
field: string;
end;
var
Rec: PRec;
begin
GetMem(Rec, SizeOf(Rec^));
// Oops. Rec^ is uninitialized. This assignment isn't safe.
Rec^.field := IntToStr(4);
// Even if the assignment were OK, FreeMem would leak the string.
FreeMem(Rec);
end;
इसे ठीक करने के दो तरीके हैं।
GetMem(Rec, SizeOf(Rec^));
Initialize(Rec^);
Rec^.field := IntToStr(4);
Finalize(Rec^);
FreeMem(Rec);
अन्य प्रकार अवगत कार्यों का उपयोग करने के लिए है:
New(Rec);
Rec^.field := IntToStr(4);
Dispose(Rec);
ऐसा लगता है कि मैं सोच रहा था, लेकिन यह 200 9 में एवी नहीं है, जो मुझे विश्वास है कि आप क्या कह रहे थे। –
यह एवी नहीं है क्योंकि डेल्फी 200 9 में $ constCHECKS चालू होने पर "कॉन्स्ट" इसकी कार्यक्षमता खो देता है। –