Leak in MiniZip - iphone

I'm using MiniZip to unzip a file in an iPhone project. Everything works fine but i get a leak in instruments in the MiniZip code on this line :
unzip.c
line 493
s=(unz_s*)ALLOC(sizeof(unz_s));
*s=us;
unzGoToFirstFile((unzFile)s);
return (unzFile)s;
I understand that the var allocated with ALLOC is returned and not deallocated. In objective-C i would simply do an autorelease, but how can i achieve that in plain C ?
Thanks,
Vincent.

The caller of that method is responsible for s and must free() it when it is no longer required to avoid the memory leak. This is the convention in C.
You would have to tie in a 3rd-party GC library, perhaps something like Hans Boehm's GC for C/C++. However, my suggestion would be to just free the memory when it is appropriate on your own. You'll run into less hassles that way.

free(s);
(filler to 15 characters)

unzOpen() is intended to allocate and return a handle s to the caller. After you got that handle you may operate on this zip-archive (i.e. search for a file, inflate files from archive, ...). After all operations are finished, you have to explicitiely close zip-archive by calling unzClose(s) which de-allocates s for you.
Here is an example to extract a specific file from an archive:
unzFile hArchive;
unsigned char buffer[1024];
hArchive = unzOpen("abc.zip");
if (hArchive != NULL) {
if (unzLocateFile(hArchiveFile, "example.txt", 0) == UNZ_OK) {
if (unzOpenCurrentFile(hArchiveFile) == UNZ_OK) {
while (unzReadCurrentFile(hArchiveFile,buffer,sizeof(buffer)) > 0) {
/* write buffer to another file / to stdout / ... */
}
unzCloseCurrentFile((unzFile) *hArchiveFile);
}
}
}
unzClose(hArchive);
see http://www.winimage.com/zLibDll/minizip.html for further information.

Whatever function this is in, the problem is not in that function. It's supposed to return an allocated object, not uselessly allocate-and-free before returning. The problem is in your use of the library. You're never calling the function to free the pointer you obtained from calling this function.

Related

Coverity and never freed storage

I have a library that allocates objects. In most cases these objects are never freed by the applications. Naturally, Coverity flags each and every use of this library with leaked_storage.
I really do not want to add 100s of Coverity annotations, is it possible to suppress these warnings from inside the library?
If you have a function that allocates and returns memory that is never intended to be freed, I recommend saving the returned pointer in a program-lifetime variable. This should make the tool think the memory might be freed by someone other than the caller, and hence not report memory leaks involving that allocator.
For example (not tested, I don't have access to the tool anymore):
#ifdef __COVERITY__
static void *dummy;
#endif
void *never_freed_malloc(size_t size)
{
void *ret = malloc(size);
#ifdef __COVERITY__
dummy = ret; /* suppress memory leak reports */
#endif
return ret;
}
With this change, Coverity sees that ret "escapes" into the program-lifetime variable dummy, and will therefore not assume that the caller must free it.
The #ifdef __COVERITY__ means that dummy is only seen by the Coverity compiler, so won't affect run-time performance. See also Coverity. Configure to ignore certain sections of the source code.

Different block behavior between debug and release configuration

My program works perfectly. I assure you with my life, 0 bugs. Proudly, I tried to package the application as an .ipa file for ad-hoc distribution to my beta tester using TestFlight.
The program didn't work. Animations which are supposed to happen never happened. Network code breaks. The button to fade out the music beautifully didn't do anything at all.
It turns out that the culprit is the new and shiny blocks. When I test my program in the Simulator or on my device, I used the default "Debug" build configuration. But when I archive it for distribution (and I believe later for submission to the App Store), XCode uses another configuration which is "Release". Investigating further, the difference is due to the optimization level (you can find it on XCode's Build Settings): Debug uses None (-O0) but Release uses Fastest, Smallest (-Os). Little did I know, that it's Fastest, Smallest, and Doesn't Work (tm). Yes, blocks behave differently between those 2 configurations.
So, I set out to solve the problem. I've simplified my soon-to-change-the-world app into its bare bones, shown in the image I've attached to this post. The view controller has an instance variable x with initial value 0. If we press b, it will spawn a thread that will continuously check the value of x, changing the bottom label when x becomes 1. We can change the value of x using button a.
Here is my naive code (I'm using ARC btw):
#implementation MBIViewController
{
int _x;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_x = 0;
}
- (void)updateLabel
{
self.topLabel.text = [NSString stringWithFormat:#"x: %d", _x];
}
- (IBAction)buttonAPressed:(id)sender {
_x = 1;
[self updateLabel];
}
- (IBAction)buttonBPressed:(id)sender {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (_x != 1) {
// keep observing for value change
}
dispatch_async(dispatch_get_main_queue(), ^{
self.bottomLabel.text = #"b changed me becase x changed!";
});
});
}
#end
_x is an instance variable, so it is reasonable to think that the block will access it using a pointer to "self", not on a local copy. And it works on the debug configuration!
But it doesn't work on Release build. So perhaps the block is using a local copy after all? OK, so let's explicitly use self:
while (self->_x != 1) {
// keep observing for value change
}
Doesn't work either in Release. OK, so let's access the damn variable directly using pointer:
int *pointerToX = &_x;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (*pointerToX != 1) {
// keep observing for value change
}
// other codes
});
Still doesn't work. This is when it dawned to me that the smart optimizing compiler assumes that there is no possible way in this multithreaded world that the result of the comparison will change, so perhaps it substituted it to be always TRUE or some other voodoo.
Now, when I use this, things start working again:
while (_x != 1) {
// keep observing for value change
NSLog(#"%d", _x);
}
So, to bypass the compiler optimizing out the comparison, I resorted to making a getter:
- (int)x
{
return _x;
}
And then checking the value using that getter:
while (self.x != 1) {
// keep observing for value change
}
It now works, because self.x is actually a call to a function and the compiler is polite enough to let the function actually do its job. However, I think this is a rather convoluted way to do something so simple. Is there any other way you would have coded it, another pattern that you will use, if you are faced with the task of "observing for change of value inside a block"? Thanks a lot!
If you use a variable and do not modify it in a loop, the compiler optimization can cause the actual access to the variable to be optimized out, because your statement can be evaluated beforehand at compile time.
In order to prevent this, you can use the "volatile" keyword, which prevents the compiler from applying this type of optimization.
It does work with getters and setters, because then you need to send a message to your instance, which serves as a synchronization point.
Try declaring _x as follows:
__block int _x;
Normally variables that are also used in blocks are copied. This will indicate to the compiler that if _x is modified in the block the changes should be visible outside it. It might fix your problem.

Need an iPhone Programmer judge every step and every pointer == nil?

for example:
NSString *myString = [[NSString alloc] init];
if (nil == myString) {
return;
}
Need I do this??Thank you!
No, you don't need to do that, and I can't say I've ever seen code that made pervasive use of that pattern.
Also, the if statement can be shortened to:
if (! myString) {
return;
}
...which is equivalent though no less superfluous. Checking for nil can be useful, but is typically not done immediately after object instantiation. Instead the typical case is to do it to ensure that an object is not over-released, for instance using a pattern like:
if (myObj) {
[myObj release];
myObj = nil;
}
Note that calling any method on nil is allowed in Objective-C, so less harm is caused by an unexpected nil value floating around than in languages like Java where attempting to do anything with a null reference throws an exception.
Objective-C allows to call on nil pointers, that differs the language from many others and allows to skip some checks. Of course, it's still wise to check for == nil in some particular cases, however, you don't have to check every step in the code. Take a look at Apple's documentation and samples and try to follow their style.
Frankly, most iPhone app code produced these days assumes that an out-of-heap condition (the only logical reason for such a simple instantiation operation to fail) never occurs in normal operation. Only when creating large (eg, image) objects might one check for allocation failure.
Of course, init routines can fail for a host of reasons, so checking for nil following a complex instantiation operation may be warranted (depending on the object type). (And remember that many other methods of some objects can return nil under some circumstances as well, so you need to read the specs and code accordingly.)

Trying to understand blocks on iOS

I am trying to understand how to use blocks on iOS. I have read Apple's docs but, as usual, they are vague and incomplete and several essential bits of information are not mentioned. I have also googled around without success. This is what I am trying to do as an exercise to understand that.
I have created a block to read a string and compare the string to the previous read. If the strings are not the same, return YES, if they are the same, return NO.
This is how I did:
I declared this on .h
BOOL (^differentStrings)(void);
I declared this on .m, inside viewDidLoad in a viewController
__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){
currentString = [self getString];
NSLog(#"%#", currentString); // not printing anything on console
if (![currentString isEqualToString:previousString]) {
previousString = currentString;
return YES;
} else {
return NO;
}
};
This is how I use: I have a thread that does this:
if (differentStrings)
NSLog (#"strings are different);
These are the problems I have:
the block always return YES (strings are different)
I am not comfortable declaring this inside videDidLoad. How should I declare this, so I can use it globally as a method? Should I put this like I would with a method?
I am calling a method "getString" inside the block. Is it OK?
I find strange to declare the block variables on .m. As I see, I should declare the block variables on .h and then just use them on .m. I have tried to do that, but received an error.
I have setup a debugging point on the first line of the block but it is not stopping there;
NSlog line inside the block do not prints anything. Isn't the block being called?
Can you guys help me with this?
You're misunderstanding how blocks work. (Okay, so that's kinda obvious.) In the same way that previousString is a variable pointing to an NSString, differentStrings is a variable pointing to a block. Not the result of running the block, but rather, the block itself. That is, after you do this:
__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){
currentString = [self getString];
NSLog(#"%#", currentString); // not printing anything on console
if (![currentString isEqualToString:previousString]) {
previousString = currentString;
return YES;
} else {
return NO;
}
};
differentStrings is a variable pointing to the block.Thus, when you do this:
if (differentStrings)
…you're simply checking whether differentStrings contains something other than 0 or NULL. Since it contains a block, it is not empty, so it evaluates to true.
Remember: differentStrings is a block variable, not a BOOL variable. It contains a block (a function, if you will), which when called will return a bool. Thus, in order to actually run the block, you need to call it. Like this:
differentStrings();
or, in your case:
if (differentStrings()) {
NSLog (#"strings are different");
}
Edit: As pointed out in the comments, since differentStrings is an instance variable, you need to copy it, just like you'd call retain on any other object assigned to an instance variable. (For technical reasons I won't go into now, you should always use copy with blocks instead of retain.) Likewise, you'll need to call release on it at some point later, perhaps in your dealloc method.
I don't believe you're actually executing the block. I think your code should be
if (differentStrings())
{
NSLog (#"strings are different);
}
Treat a block like a function. I think you were just checking to see whether the block had been defined, not executing it.
Also, if you don't need to access an NSString outside of the block, you could get rid of the __block qualifier and move the currentString declaration inside of the block.
If you need another resource on blocks, I cover them in the fall session of my advanced iOS development course on iTunes U. I describe block syntax in the Understanding Cocoa session, and their use in Grand Central Dispatch within the multithreading session. The course notes also have links to some sample applications that use blocks in different ways.
I also can't recommend highly enough that you watch the WWDC 2010 video sessions 206 - Introducing Blocks and Grand Central Dispatch on iPhone and 211 - Simplifying iPhone App Development with Grand Central Dispatch.

Can't fix Severe Memory Leak from Open AL

I'm nearing the end of a big iPhone project and whilst checking for memory leaks stumbled on this huge one. I implemented the sound following this tutorial:
http://www.gehacktes.net/2009/03/iphone-programming-part-6-multiple-sounds-with-openal/
Works a charm, a lot of people use it but I get a huge leak a start of the project when sound is initially loaded in. Below are the lines of code that start of the leak:
[[Audio sharedMyOpenAL] loadSoundWithKey:#"music" File:#"Music" Ext:#"wav" Loop:true];
[[Audio sharedMyOpenAL] loadSoundWithKey:#"btnPress" File:#"BtnPress" Ext:#"wav" Loop:false];
[[Audio sharedMyOpenAL] loadSoundWithKey:#"ting1" File:#"GlassTing1" Ext:#"wav" Loop:false];
etc. etc. it loads in 20 sounds altogether. And more specifically in the Audio.m file this chunk of code:
+ (Audio*)sharedMyOpenAL {
#synchronized(self) {
if (sharedMyOpenAL == nil) {
sharedMyOpenAL = [[self alloc] init]; // assignment not done here
}
}
return sharedMyOpenAL;
}
I am unsure how to resolve this and any help on the matter would be greatly appreciated.
Thanks.
Isn’t the “leak” simply the Audio singleton? I am not sure how the leak detection works, but from a certain viewpoint most singletons are leaks, since they only release memory after your application exits.
If this really is the case, then it depends on whether you need to release the memory used by the sounds. The memory usage should not go up, so you don’t have to worry about the “traditional leak” scenario where your application takes more and more memory until it gets killed. The code you are using does not seem to support sound unloading, so that if you want to release the memory, you’ll have to add that code yourself.
And a personal viewpoint: Writing a sound effect engine using a singleton is not a good design. Managing the sounds becomes a pain (this is exactly the problem you are facing), the singleton adds a lot of unnecessary boilerplate code, etc. I see no reason the sounds should not be simple separate objects with their own lifecycle – this is the way I’ve done it in my attempt at an OpenAL SFX engine. Of course, I could be wrong.
Update: I suppose the magic ‘assignment not done here’ is the key. The singleton code is taken from the Apple documentation, but somebody inserted an extra assignment. The sharedFoo method should look like this:
+ (MyGizmoClass*)sharedManager
{
#synchronized(self) {
if (sharedGizmoManager == nil) {
[[self alloc] init]; // assignment not done here
}
}
return sharedGizmoManager;
}
When you perform the extra assignment to self, you create the leak you are looking for.