Guaido79
Guaido79

Reputation: 1261

Objective-C malloc with c array of array

I have as property in a view, an array of array like this:

@interface MyView : UIView

@property (nonatomic) CGPoint **matrix;

@end

in the controller that own this view I have load the data in the -viewDidLoad and free memory in the -viewDidUnload like this:

- (void)viewDidLoad
{

    self.myView.matrix = malloc(sizeof(CGPoint*) * array1Size);
    for (int k = 0; k < array1Size; k++) {
        self.myView.matrix[k] = malloc(sizeof(CGPoint) * innerArraySize);
    }
}

- (void)viewDidUnload
{
    for (int k = 0; k < array1Size; k++) {
        free(self.myView.matrix[k]);
        self.myView.matrix[k] = nil;
    }
    free(self.myView.matrix);
    self.myView.matrix = nil;
    [self setMyView:nil];
    [super viewDidUnload];
}

While profiling I see a leak here. Can someone help me where I'm wrong?

thanks

update:

i try to remove free code from viewDidUnload and use dealloc like this:

-(void)dealloc {
    [self freeArray];
}

- (void) freeArray {

    for (int k = 0; k < 5; k++) {
        free(self.myView.matrix[k]);
        self.myView.matrix[k] = NULL;
    }

    free(self.myView.matrix);
    self.myView.matrix = NULL;
}

then I embed init code in:

if (self.graphView.matrix == NULL) {
    ...
}

now no more leak, THANKS!

Upvotes: 1

Views: 2478

Answers (2)

bbum
bbum

Reputation: 162712

Use an array of CGPoint:

@property (nonatomic) CGPoint *matrix;

.... init ...
{
   ...
   matrix = (CGPoint*) malloc(arraySize * sizeof(CGPoint));
 ...
}

- (void) dealloc
{
    free(matrix);
}

Then you simply set/get CGPoint structures directly in the array:

CGPoint someCGPoint = {0,0};
matrix[i] = someCGPoint;

someCGPoint = matrix[i];

That'll be faster and more memory efficient than CGPoint**. And your leak is gone.

Upvotes: 0

Nikolai Ruhe
Nikolai Ruhe

Reputation: 81868

Your code does not make sure that each setup of the matrix is matched by exactly one tear down. For example, viewDidUnload is not guaranteed to be called. Also, you have no guards against duplicate setup or tear down.

If you really need the C array of arrays, a better approach would be to create it in the initializer of the view (initWithFrame: or initWithCoder:) and remove it in its dealloc.

Edit: To alleviate your concerns regarding dealloc and ARC:

You can certainly override dealloc in ARC and rely on it being called. The only difference is that you cannot explicitly call the overridden implementation ([super dealloc]). ARC will insert that for you.

Upvotes: 3

Related Questions