quantumpotato
quantumpotato

Reputation: 9767

How do I release C style arrays?

I have a QuantumClone class which has an array of CGPoints. The single QuantumPilot object creates a QuantumClone at the beginning of each level. During the next level the QuantumPilot records its velocities to its QuantumClone. At the beginning of a new level the game loop runs this code

QuantumClone *c = [[self.pilot clone] copy];
c.bulletDelegate = self;
c.weapon = self.pilot.weapon;
[self.clones addObject:c];

But eventually the game will be reset and each QuantumClone object in the clones NSMutableArray will be removed.

Am I leaking memory by assigning values to the CGPoint pastVelocities[4551] ?

How do I reset these? I can't release them since they are not Objective-C objects. Do I need to call C functions to release this memory?

@interface QuantumClone : QuantumPilot <NSCopying> {
  CGPoint pastVelocities[4551];
}

- (id)copyWithZone:(NSZone *)zone {
    QuantumClone *c = [[[QuantumClone alloc] init] autorelease];
    c.weapon = self.weapon;
    for (NSInteger i = 0; i < 4551; i++) {
        [c recordVelocity:pastVelocities[i] firing:pastFireTimings[i]];
    }
    [c recordLatestIndex:timeIndex];
    return c;
}

- (void)recordVelocity:(CGPoint)vel firing:(BOOL)firing {
    CGPoint p = pastVelocities[timeIndex];
    p.x = vel.x;
    p.y = vel.y;
    pastVelocities[timeIndex] = p;
    bool fired = firing;
    pastFireTimings[timeIndex] = fired;
    timeIndex++;
}

@interface QuantumPilot : CCNode {}
....
@property (nonatomic, retain) QuantumClone *clone;

- (void)copyDeltas {
    [self.clone recordVelocity:ccp(self.vel.x, -self.vel.y) firing:self.firing];
}

- (void)createClone {
    self.clone = [[[QuantumClone alloc] init] autorelease];
    self.clone.active = YES;
    self.clone.weapon = self.weapon;
}

Upvotes: 1

Views: 168

Answers (2)

jweyrich
jweyrich

Reputation: 32260

Am I leaking memory by assigning values to the CGPoint pastVelocities[4551] ?

Short answer: No.

Long answer: The array in your code is a big chunk of contiguous memory where all CGRects live in, and it has automatic storage, which means it will be allocated and deallocated automatically (when it goes out of scope). In other words, when its parent object is destroyed, the array will be gone along with those 4551 objects.

You can verify its size by printing the result of sizeof(pastVelocities). Dividing the result by sizeof(CGRect) will tell you how many objects of this type can be stored in it.

A deallocation must be married to an explicit allocation. You only need to release memory that is allocated dynamically (explicitly), for example, using the alloc function family (malloc, calloc, realloc, etc).

How do I reset these?

memset(pastVelocities, 0, sizeof(pastVelocities));

This will reset the entire array.

Upvotes: 2

iccir
iccir

Reputation: 5128

jweyrich beat me to it, but I'll go ahead and post this in case it helps ;)

––

You aren't leaking. The runtime allocates enough memory to hold all ivars. In this case, each QuantumClone instance will use ~18k (~36k on 64-bit) more memory than a QuantumPilot, since you have told the runtime that it needs to allocate enough ivar storage for 4551 CGPoints.

If pastVelocities were a CGFloat * rather than a CGFloat[4551], you would need to manually allocate the memory via malloc and then call free in -dealloc. However, by declaring it as a fixed size C-array, the runtime handles it (but at the expense of making every QuantumClone a rather huge object).

That said, this whole approach seems fragile. Why 4551? Why C arrays? There is nothing wrong with using C arrays for performance, but I strongly suspect this is premature optimization.

Upvotes: 1

Related Questions