2

I have a class AudioManager with a member of type AudioBufferList *. (This is a struct declared in the CoreAudio framework). Since AudioBufferList is not a NSObject, I cannot retain it, so I have to alloc/free it (correct me if I'm wrong).

My question is, where is the 'right' place to free it? Currently I am doing it in the dealloc method of AudioManager. If I understand correctly, this method is invoked automatically once the release message is sent to the instance of AudioManager --- is that true? Is there any other recommended practice regarding using alloc/free on non-objects members of Objective-C objects?

Edit:

From Apples documentation:

Subclasses must implement their own versions of dealloc to allow the release of any additional memory consumed by the object—such as dynamically allocated storage for data or object instance variables owned by the deallocated object. After performing the class-specific deallocation, the subclass method should incorporate superclass versions of dealloc through a message to super:

Which makes things a little bit clearer - but more insights are appreciated.

Itamar Katz
  • 9,544
  • 5
  • 42
  • 74

2 Answers2

1

Yes, you do need to malloc/free the memory. There's a great answer/example here, proper memory-management included:

iPhone: AudioBufferList init and release

As for "when", you'll want to not only free the memory when the AudioManager is released, but also if the value of your AudioBufferList is ever changed. Eg. If the pointer is initially referencing some "instance A" of the AudioBufferList struct, and you change it to point to some "instance B" of the AudioBufferList struct, then you'll want to free the memory for "instance A," otherwise it may be lost. (And the memory will be leaked.)

One important point, and maybe it's one that you knew but accidentally mistyped: dealloc is not called when release is sent to an object. An instance of NSObject is only deallocated when its retain count has reached zero. An object could have a retain count of 2, and after being sent [myObject release], its retain count would become 1. But it will not be sent the dealloc message, as this implies that some other object still "owns" that instance, and is relying on the object to remain allocated and available.

Community
  • 1
  • 1
Craig Otis
  • 31,257
  • 32
  • 136
  • 234
  • Yep, completely clear that one need to free() before assigning a pointer to point to another address... Thanks for the clarification. – Itamar Katz Jan 10 '11 at 20:26
0

You should not need to do malloc or free on it. You would use a struct, such as CGRect or AudioBufferList, the same way you would use an int or double. There is no issue with retain, alloc, dealloc, release, etc, on non-object types.

As for the dealloc method of AudioManager, it will not automatically be called when the release message is sent, it will automatically be called when the retain count equals 0. Sending a release message to an object decreases the retain count by 1. It could still have other things that retain it, in which case it will not yet be dealloced.

Edit

Example of how Apple uses struct types:

CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
{
  CGRect rect;
  rect.origin.x = x; rect.origin.y = y;
  rect.size.width = width; rect.size.height = height;
  return rect;
}
GendoIkari
  • 11,734
  • 6
  • 62
  • 104
  • But non-object types (such as `AudioBufferList`) still might need to be 'c-style' malloc/free, no? I mean, sometimes you need to dynamically allocate memory. (And thanks for the 2nd part of your comment). – Itamar Katz Jan 10 '11 at 19:07
  • Unless there's something special about AudioBufferList that's not clear, then no. For example, look at Apple's method, CGRectMake, which I'll post in an edit to my answer. – GendoIkari Jan 10 '11 at 19:08
  • Of course, if you only want to return a copy of your data type. But what if you have to create an array of `CGRect`, of size which is knows only in run-time? Then, as far as I know, you must allocate memory dynamically for it. – Itamar Katz Jan 10 '11 at 19:14
  • There's pretty much always a way to avoid actually using `malloc()` and `free()`, but it's not always worth the trouble. For an array of `CGRect`, for instance, you can use a `NSArray` of `NSValue`. – Steven Fisher Jan 10 '11 at 19:35
  • The question asks about a pointer to an AudioBufferList structure, which will be a null pointer for a newly allocated object. Therefore, malloc and free are required to allocate the memory that is pointed to. – ughoavgfhw Jan 10 '11 at 20:53