4

I know its a little bit general , but we did EVERY possible thing to find what it is, and we just couldn't .

We have this crash that happens here and there, not always, on this line :

[self.imageOperationQueue addOperationWithBlock:^
 {
    if(!data)
        return ;
    UIImage *image=[[UIImage alloc] initWithData:data]; // *** CRASH !

The crash log says :

malloc: *** error for object 0x7fecdb06e5c0: double free
*** set a breakpoint in malloc_error_break to debug

As you can see, and upon our check , data is not nil when we are creating the image , we have also tried with : [UIImage initWithData:data]; without allocation , but same thing.

EDIT: this is how the code looks like after this row :

       if(!data)
          return ;


      UIImage *image=[[UIImage alloc] initWithData:data];
      UIImageView *modelview=[self.allImageView objectAtIndex:index];
      float newH=image.size.height* (1.65*modelview.frame.size.width/image.size.width);
      CGSize s=CGSizeMake(1.65*modelview.frame.size.width, newH);

      if (image)
      {
          UIGraphicsBeginImageContextWithOptions(s , NO, 0.0);
          [image drawInRect:CGRectMake(0, 0, s.width, s.height)];

          image = UIGraphicsGetImageFromCurrentImageContext();
          UIGraphicsEndImageContext();
      }
Curnelious
  • 1
  • 16
  • 76
  • 150

1 Answers1

3

Your data is likely being over-released on another thread. The double-free indicates a memory management imbalance, not a nil-pointer.

If I had to predict the problem, I'd guess you're generating data from an unsafe pointer, maybe the result of a CoreGraphics call, or a NSData over malloc'ed memory that gets freed behind your back. Here's how my theory works:

  • You create the NSData over unsafe memory
  • You create this operation block, which puts a retain on the NSData
  • Somewhere else, you free the underlying memory
  • The operation block runs
  • This is the last line that uses data
  • ARC notices that and so releases data at the semicolon
  • Releasing data leads to a free()
  • Memory was already freed by someone else
  • Crash

The key is that NSData typically should be the sole owner of its memory; if it's not, then you have to be very careful, especially in multi-threaded operations.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • thanks-Please check my edit : you right i do use core graphic right after that, but the crash shows that its that line . So , bottom line how would i change this code to stop this from happen ? every time i want to load 4 next images from a server i use this block( a regular lazy loading) – Curnelious Nov 06 '14 at 12:50
  • 1
    @Curnelious - By the time you get to the failing line it's too late. – Hot Licks Nov 06 '14 at 12:53
  • The bug probably isn't here. It's probably in the code that generates data and then calls this. – Rob Napier Nov 07 '14 at 14:39