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.
Related
For example if I were to write this code:
var t = time_t()
time(&t)
let x = localtime(&t) // returns UnsafeMutablePointer<tm>
println("\(x.memory.tm_hour): \(x.memory.tm_min): \(x.memory.tm_sec)")
...would it also be necessary to also do the following?
x.destroy()
x.dealloc(1)
Or did we not allocate the memory and so therefore don't need to dismiss it?
Update #1:
If we imagine a function that returns an UnsafeMutablePointer:
func point() -> UnsafeMutablePointer<String> {
let a = UnsafeMutablePointer<String>.alloc(1)
a.initialize("Hello, world!")
return a
}
Calling this function would result in a pointer to an object that will never be destroyed unless we do the dirty work ourselves.
The question I'm asking here: Is a pointer received from a localtime() call any different?
The simulator and the playground both enable us to send one dealloc(1) call to the returned pointer, but should we be doing this or is the deallocation going to happen for a returned pointer by some other method at a later point?
At the moment I'm erring towards the assumption that we do need to destroy and dealloc.
Update #1.1:
The last assumption was wrong. I don't need to release, because I didn't create object.
Update #2:
I received some answers to the same query on the Apple dev forums.
In general, the answer to your question is yes. If you receive a pointer to memory which you would be responsible for freeing in C, then you are still responsible for freeing it when calling from swift ... [But] in this particular case you need do nothing. (JQ)
the routine itself maintains static memory for the result and you do not need to free them. (it would probably be a "bad thing" if you did) ... In general, you cannot know if you need to free up something pointed to by an UnsafePointer.... it depends on where that pointer obtains its value. (ST)
UnsafePointer's dealloc() is not compatible with free(). Pair alloc() with dealloc() and malloc and co. with free(). As pointed out previously, the function you're calling should tell you whether it's your response to free the result ... destroy() is only necessary if you have non-trivial content* in the memory referred to by the pointer, such as a strong reference or a Swift struct or enum. In general, if it came from C, you probably don't need to destroy() it. (In fact, you probably shouldn't destroy() it, because it wasn't initialized by Swift.) ... * "non-trivial content" is not an official Swift term. I'm using it by analogy with the C++ notion of "trivially copyable" (though not necessarily "trivial"). (STE)
Final Update:
I've now written a blogpost outlining my findings and assumptions with regard to the release of unsafe pointers taking onboard info from StackOverflow, Apple Dev Forums, Twitter and Apple's old documentation on allocating memory and releasing it, pre-ARC. See here.
From Swift library UnsafeMutablePointer<T>
A pointer to an object of type T. This type provides no automated
memory management, and therefore the user must take care to allocate
and free memory appropriately.
The pointer can be in one of the following states:
memory is not allocated (for example, pointer is null, or memory has
been deallocated previously);
memory is allocated, but value has not been initialized;
memory is allocated and value is initialized.
struct UnsafeMutablePointer<T> : RandomAccessIndexType, Hashable, NilLiteralConvertible { /**/}
I am trying my best to find memory leaks in a very important module in our project and got a code snippet like this:
PyObject* python_func( const char* str )
{
..........................
boost::python::list obj;
obj.append(str);
obj.ptr()->ob_refcnt++; //this is necessary??
return obj.ptr();
}
I am confused about this line: obj.ptr()->ob_refcnt++;
I think ob_refcnt is maintained by python internally for gc, we can't operate it so obviously cause this will lead to memory leaks, on the other hand, obj is going to leave its scope, I am not sure if boost::python::list deconstructor will decrease ob_refcnt, if that's true, remove that line, the resource obj hold would be released, that will lead to a crash.
So my question is whether obj.ptr()->ob_refcnt++; is necessary, and why?
The reason the code increases the reference count is that python_func is intended to return a new reference to the object. (A new reference is one that has the reference count already increased -- returning a new reference allows the function to create new objects, such as a new list in this case.) On the other hand, the ptr() member function returns a borrowed reference to the object.
As you correctly surmised, if the code failed to increase the reference count of the borrowed reference, the destructor of boost::python::list would decrease the reference count and the returned object would be invalid.
Note that you should never directly access the ob_refcnt member of PyObject. The proper way to increase the reference count is through the use of the Py_INCREF macro or its boost::python equivalent boost::python::incref:
return boost::python::incref(obj.ptr());
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Objective-C/iPhone Memory Management Static Variables
I'm looking through a contractor's code who is no longer with us and I'm not sure how to handle memory management in this case. There is a
static NSArray *_sharedSample = nil;
declared in a .m file. Then they do
_sharedSample = [[NSArray arrayWithObjects:someinfo here, nil] retain];
So in this case, where is the release? I've searched for _sharedSample throughout the project, and I do not see a [_sharedSample release];. Do static objects work differently? I thought I'd have to release it somewhere. Thanks.
A static variable is effectively an application global, no matter how many objects, methods or functions know about it.
You have the option to just leave it. The memory will be freed by the system when the app quits.
You should initialize static variables to nil (zero) in the declaration line as you have here. Static variables are allocated earlier in the launch process than the call to the app's main() function. This means that no allocation pools will yet exist.
If you attempt to create an Objective-C object before the first pool is created you may cause a memory leak. (You will see a "just leaking" message in the debugger console if you do.)
If you do release a static variable along the way, you should also immediately set it to nil to prevent errors with over-releasing or dangling pointers.
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.
I'm somewhat new to objective-c and I'm not sure what the correct memory management for this code is.
const unsigned char * data =(const unsigned char *) [string UTF8String];
When I call free on data I get an error. Do I need to clean up after this call?
No. "UTF8String" does not contain the words alloc, copy, retain, or create. Thus, you're not responsible for that memory.
Note that if you want that data to stick around after string is released, you should copy it; by the contract, you're not responsible for that memory, but you are also not guaranteed that it will last beyond the scope of the object that gave it to you.
You do not need to free it.
In Cocoa, if a method does not contain the words alloc, init, or copy, you do not own the object that is returned from said method.
-UTF8String actually points to the cstring representation of the NSString object you are calling it on. When the object's state changes, the UTF8String also changes.
As stated in the documentation, it is automatically freed the same way an autoreleased object would be.
technically speaking, free() is used to remove memory allocated using malloc() from the heap.
malloc() was not used to allocate the memory. remember that objective-c is c with extensions.
the data variable will remain in memory based on the c language 'scoping' rules.