2012-03-05 32 views
6

इस सी को देखते हुए ++ कोड:JNA स्मृति रिसाव

void LoadData(char** myVar) 
{ 
    std:: string str("[Really Long String Here]"); 
    unsigned int size = str.length() + 1; 
    *myVar = new char[size]; 
    strncpy(*myVar, str.c_str(), size); 
} 

और यह JNA जावा:

Pointer myVar = new Memory(Pointer.SIZE); 
this.Lib.LoadData(myVar); 
this.someVar = myVar.getPointer(0).getString(0); 

मैं मेमोरी लीक हो रही है, के रूप में मैं इसे समझ, getPointer (0) एक सूचक बनाना चाहिए ऑब्जेक्ट जिसे अंतिम रूप देने पर जारी किया जाना चाहिए(), लेकिन ऐसा नहीं लगता है।

क्या मुझे कुछ याद आ रही है? यह spec के लिए लगता है ... और मैं उपरोक्त समारोह को C++ ठीक में कोई रिसाव के साथ चला सकते हैं।

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

मैं कुछ दिनों के लिए इसके खिलाफ अपने सिर को टक्कर लगी हूं और यह मुफ्त मेमोरी के प्रयास के रूप में कुछ छोटे से लापरवाही करने के लिए बेकार है। जहाँ तक मैं कह सकता हूं कि मैं केवल जावा में मैन्युअल रूप से मुक्त स्मृति कर सकता हूं मेरे पास पता है, लेकिन मैं नहीं देख सकता कि मैं इसे कैसे प्राप्त करूंगा।

संपादित करें:

कोई बात नहीं, मैं भी नहीं लगता कि यह विस्तार के बिना JNA के माध्यम से मैन्युअल मुक्त करने के लिए एक तरीका है कि ...

उत्तर

3

सी ++ पुस्तकालय को यह समारोह जोड़ें ...

void FreeData(char** myVar) 
{ 
    delete [] *myVar; 
} 

और फिर इस JNA कोड

Pointer myVar = new Memory(Pointer.SIZE); 
this.Lib.LoadData(myVar); 
this.someVar = myVar.getPointer(0).getString(0); 
this.Lib.FreeData(myVar); 

इस तरह आप आवंटित कर सकते हैं और सी में स्मृति को नष्ट ++।

+0

यह अब तक काम करता प्रतीत होता है, लेकिन क्या डेटा मुक्त करने के लिए जेएनए में वास्तव में कोई अन्य तरीका नहीं है? :( – StrangeWill

+1

जेएनए एक मूल पुस्तकालय के लिए सिर्फ एक आवरण है। यह मूल स्मृति का प्रबंधन नहीं करता है, विशेष रूप से प्रत्यक्ष देशी बफर। यह मूल पुस्तकालय डिजाइनर का कार्य है जो पुस्तकालय के उपयोग की स्मृति को आवंटित/डिलीकेट करने के लिए इंटरफेस प्रदान करता है। – ecle

+1

जेएनए के पास है स्मृति को मुक्त करने के लिए आंतरिक तरीकों, बस अजीब है कि मुझे इसे फिर से कार्यान्वित करना होगा क्योंकि यह सब जेएनए में संरक्षित है। – StrangeWill

0

के बजाय myVar = नए चार [आकार]

उपयोग

*myVar = malloc(size); 
strncpy(*myVar, str.c_str(), size); 

सरणी की तरह नष्ट कर दिया जाना चाहिए: [] * myVar हटाना;

जेएनए प्रॉली ऐसा करने के लिए नहीं जानता है।

+1

'strlen (आकार)'? –

+0

हेड-अप, निकलास के लिए धन्यवाद, संपादित। –

+0

अभी भी तेजी से लीक, अभी भी तेजी से। :( – StrangeWill

1

कॉलर में आवंटित, कैली नहीं।

उदाहरण के लिए:

int LoadData(char* buf, int maxlen) { 
    std:: string str("[Really Long String Here]"); 
    strncpy(buf, str.c_str(), maxlen); 
    if (str.length() < maxlen) 
     return str.length(); 
    return maxlen; 
} 

फिर जब आप जावा से कहते हैं, उचित आकार का एक byte[] में गुजरती हैं। ध्यान दें कि यह कार्यान्वयन संभावित रूप से बहुत अक्षम है, लेकिन विचार यह है कि आप आम तौर पर एक संदर्भ में स्मृति आवंटित नहीं करना चाहते हैं और इसे दूसरे में विचलित करना चाहते हैं।

+1

कार्यान्वयन में: char * buf 10 बाइट्स, 10k या 150k हो सकता है, संभवत: पूर्ण कोड लागू करने के बाद। कुछ मेग्स आवंटित करने और केवल अक्षम कार्यान्वयन के साथ (मेरा सॉफ़्टवेयर कर सकता है, लेकिन मैं ' एमएनए के साथ ऐसा करने के लिए _right_ तरीके में अधिक रुचि रखते हैं) – StrangeWill

+0

यदि आप कैली को स्टोरेज प्रबंधित करना चाहते हैं, तो आप "कॉन्स char *" वापस कर सकते हैं; जेएनए सामग्री को जावा स्ट्रिंग में कॉपी करेगा, जिसके बाद आप हैं बफर सामग्री को संशोधित करने और/या इसे हटाने के लिए सुरक्षित।यदि आप पॉइंटर वापस करते हैं, तो आप स्मृति प्रतिलिपि से बच सकते हैं जब तक कि जावा पक्ष को वास्तव में डेटा को देखने की आवश्यकता न हो। ऐसा करने का "सही" तरीका इस बात पर निर्भर करता है कि आपके प्रोग्राम के कौन से हिस्सों (जावा या मूल) को डेटा तक पहुंचने की आवश्यकता है, कितनी बार और बफर कब तक रहेंगे। – technomage

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