2015-09-03 4 views
6

मैं एक सूचक द्वारा संदर्भित chars की एक सरणी में (संभावित रूप से) बहुत बड़ा पूर्णांक मान संग्रहीत करने के लिए कोड लिख रहा था। मेरे कोड इस तरह दिखता है:पॉइंटर्स और "अस्थायी पायथन संदर्भ के असुरक्षित सी व्युत्पन्न को संग्रहीत करना"

cdef class Variable: 

    cdef unsigned int Length 
    cdef char * Array 

    def __cinit__(self, var, length): 
     self.Length = length 
     self.Array = <char *>malloc(self.Length * sizeof(char)) # Error 
     for i in range(self.Length): 
      self.Array[i] = <char>(var >> (8 * i)) 

    def __dealloc__(self): 
     self.Array = NULL 

जब मैं कोड संकलन की कोशिश की, मैं त्रुटि, टिप्पणी की लाइन पर "अस्थायी अजगर संदर्भ के असुरक्षित सी व्युत्पन्न भंडारण" मिला है। मेरा सवाल यह है: मैं कौन सा अस्थायी पायथन संदर्भ सी और भंडारण में प्राप्त कर रहा हूं, और मैं इसे कैसे ठीक करूं?

उत्तर

3

समस्या यह है कि हुड के तहत self.Array पर असाइनमेंट से पहले सरणी को अस्थायी चर बनाया जा रहा है और विधि समाप्त होने के बाद यह मान्य नहीं होगा।

ध्यान दें कि documentation सलाह देता है:

अजगर ढेर पर स्मृति आवंटित करने के लिए सी-एपीआई कार्यों को आम तौर पर इसके बाद के संस्करण निम्न स्तर सी कार्यों पर प्राथमिकता दी जा स्मृति वे प्रदान वास्तव में के लिए अजगर का जिम्मेदार है के रूप में आंतरिक स्मृति प्रबंधन प्रणाली। उनके पास छोटे मेमोरी ब्लॉक के लिए विशेष अनुकूलन भी हैं, जो महंगा ऑपरेटिंग सिस्टम कॉल से बचकर अपने आवंटन को गति देते हैं।

तदनुसार आप नीचे के रूप में जो इरादा के रूप में उपयोग के इस मामले को संभालने के लिए लगता है लिख सकते हैं,:

from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free 

cdef class Variable: 

    cdef unsigned int Length 
    cdef char * Array 

    def __cinit__(self, var,size_t length): 
     self.Length = length 
     self.Array = <char *>PyMem_Malloc(length * sizeof(char)) 
     #as in docs, a good practice 
     if not self.Array: 
      raise MemoryError() 

     for i in range(self.Length): 
      self.Array[i] = <char>(var >> (8 * i)) 

    def __dealloc__(self): 
     PyMem_Free(self.Array) 
2

@ RLL के जवाब (कोड को साफ करने और "सब कुछ ठीक से कर रही है" का एक बहुत अच्छा काम करता है सबसे महत्वपूर्ण बात यह है कि प्रश्न में __dealloc__ से गायब होने वाली स्मृति का विलोपन!)।

त्रुटि उत्पन्न करने वाली वास्तविक समस्या यह है कि आपके पास cimport ed malloc नहीं है। इस साइथन के कारण यह मानता है कि malloc एक पाइथन फ़ंक्शन है, जो एक पाइथन ऑब्जेक्ट लौटा रहा है जिसे आप char* पर डालना चाहते हैं। अपनी फ़ाइल के शीर्ष पर,

from libc.stdlib cimport malloc, free 

और यह काम करेगा। या वैकल्पिक रूप से PyMem_Malloc (इसे cimporting) का उपयोग करें @rll करता है और यह भी ठीक काम करेगा।

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