2010-07-23 8 views
8

मेरा ऐप मेमोरी से बाहर हो रहा है। इसे हल करने के लिए, मैं एक फ़ंक्शन में उपयोग किए जाने वाले दो बहुत बड़े सरणी मुक्त करता हूं जो एक छवि के लिए फ्रेमबफर लिखते हैं। विधि इस प्रकार है:मुफ्त() कॉल सिम्युलेटर पर काम करता है, आईपैड गुस्सा करता है। आईपैड स्मैश

-(UIImage *) glToUIImage { 
    NSInteger myDataLength = 768 * 1024 * 4; 
    // allocate array and read pixels into it. 
    GLubyte *buffer = (GLubyte *) malloc(myDataLength); 
    glReadPixels(0, 0, 768, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 

    // gl renders "upside down" so swap top to bottom into new array. 
    // there's gotta be a better way, but this works. 
    GLubyte *buffer2 = (GLubyte *) malloc(myDataLength); 
    for(int y = 0; y <1024; y++) 
    { 
      for(int x = 0; x <768 * 4; x++) 
      { 
        buffer2[(1023 - y) * 768 * 4 + x] = buffer[y * 4 * 768 + x]; 
      } 
    } 

    // make data provider with data. 
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL); 

    // prep the ingredients 
    int bitsPerComponent = 8; 
    int bitsPerPixel = 32; 
    int bytesPerRow = 4 * 768; 
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; 
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 

    // make the cgimage 
    CGImageRef imageRef = CGImageCreate(768, 1024, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); 

    // then make the uiimage from that 
    UIImage *myImage = [UIImage imageWithCGImage:imageRef]; 

    //free(buffer); 
    //free(buffer2); 

    return myImage; 
} 

नोट दो वहाँ अंत में मुक्त (बफर) और (buffer2) करने के लिए कहा जाता है? वे आईपैड सिम्युलेटर पर ठीक काम करते हैं, मेमोरी समस्या को हटाते हैं और मुझे अपमान के साथ उत्पन्न करने की इजाजत देते हैं। हालांकि, वे तुरंत आईपैड को मार देते हैं। जैसे, पहली बार यह इसे निष्पादित करता है। अगर मैं मुफ्त() कॉल को हटा देता हूं तो यह ठीक चलता है, बस एक या दो मिनट के बाद मेमोरी से बाहर चला जाता है। तो मुफ्त() कॉल डिवाइस को दुर्घटनाग्रस्त क्यों कर रहा है?

नोट - यह कॉल करने के लिए कॉल नहीं है() जो डिवाइस को स्पष्ट रूप से क्रैश करता है, यह बाद में दुर्घटनाग्रस्त हो जाता है। लेकिन ऐसा लगता है कि मूल कारण/..

संपादित करें - किसी ने पूछा है कि यह वास्तव में दुर्घटनाग्रस्त कहां है। यह प्रवाह छवि को किसी अन्य ऑब्जेक्ट पर वापस करने के लिए चला जाता है, जो इसे फ़ाइल में लिखता है। 'UIImageJPEGRepresentation' विधि को कॉल करते समय, यह EXT_BAD_ACCESS संदेश उत्पन्न करता है। मुझे लगता है कि ऐसा इसलिए है क्योंकि यूआईएममेज मैं इसे फाइल में लिखने के लिए गुजर रहा हूं भ्रष्ट, शून्य या कुछ और है। लेकिन यह तब होता है जब मैं उन दो बफर को मुक्त करता हूं।

मैं समझूंगा कि स्मृति किसी भी तरह से UIIMAGE से संबंधित थी, लेकिन यह वास्तव में नहीं होना चाहिए, खासकर जब यह सिम्युलेटर पर काम करता है। मुझे आश्चर्य हुआ कि यह कैसे है कि आईपैड 'फ्री' कॉल को कैसे संभालता है ...

उत्तर

8

docs पढ़ने से, मेरा मानना ​​है कि CGDataProviderCreateWithData केवल संदर्भ स्मृति को buffer2 द्वारा, इसे कॉपी नहीं बताया जाएगा। जब तक छवि जारी नहीं हो जाती तब तक आपको इसे आवंटित रखना चाहिए।

 
static void _glToUIImageRelease (void *info, const void *data, size_t size) { 
    free(data); 
} 

-(UIImage *) glToUIImage { 
    NSInteger myDataLength = 768 * 1024 * 4; 
    // allocate array and read pixels into it. 
    GLubyte *buffer = (GLubyte *) malloc(myDataLength); 
    glReadPixels(0, 0, 768, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 

    // gl renders "upside down" so swap top to bottom into new array. 
    // there's gotta be a better way, but this works. 
    GLubyte *buffer2 = (GLubyte *) malloc(myDataLength); 
    for(int y = 0; y
+0

मैं बस उस पर कपास भी! उत्कृष्ट स्थान, मेरे अच्छे आदमी। धन्यवाद! :) – mtrc

1

पहली चीजें पहले, आपको वास्तव में जांचना चाहिए कि क्या मॉलोक विफल हुआ है और NULL लौटाया गया है। हालांकि, अगर यह आपकी समस्या का समाधान नहीं करता है, तो डीबगर का उपयोग करें और अपने प्रोग्राम के माध्यम से कदम यह देखने के लिए कि यह कहां विफल रहता है (या कम से कम एक स्टैक ट्रेस प्राप्त करने के लिए)। मेरे अनुभव से, अप्रत्याशित क्षेत्रों में कहीं दुर्घटनाग्रस्त होने जैसी विषम विफलताओं लगभग हमेशा बफर ओवरफ्लो कुछ समय पहले मनमानी डेटा को दूषित कर रहे हैं।

+0

मुझे पता है कि यह कहां विफल रहता है (क्रमबद्ध) लेकिन ट्रेस काफी लंबा है। मैं इसे अभी संपादित कर दूंगा। – mtrc

+0

आप अतिप्रवाह के बारे में सही हो सकते हैं। अगर मैं बफर 2 मुक्त नहीं करता, तो यह ठीक काम करता है। यहां तक ​​कि अगर मैं मुक्त बफर। – mtrc

0

बफर (रों) ख़राब कर रहे हैं:

इस प्रयास करें? लूप को देखो।

for(int y = 0; y <1024; y++) 
{ 
    for(int x = 0; x <768 * 4; x++) 
    { 
      buffer2[(1023 - y) * 768 * 4 + x] = buffer[y * 4 * 768 + x]; 
    } 
} 

देना y == 0 और एक्स == (768 * 4) -1, buffer2 के सूचकांक आवंटित से अधिक आकार। इससे पहले कि बाहर की सीमा?

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