using boost::python::list as return value need increase ob_refcnt? - boost-python

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());

Related

How to get UnsafeRawPointer on the swift object?

My app uses the native C++ lib, there is a method that takes as an argument void*
void foo(void * obj) { ... }
in swift I can call this method like this
func boo(obj: MyCustomObj) {
foo(&obj)
}
and looks like really I get a void pointer on the object, but if I try to get an UnsafeRawPointer on the object like this
func boo(obj: MyCustomObj) {
var pointer = &obj <---- Use of extraneous '&'
foo(pointer)
}
I got an error
Use of extraneous '&'
What is the problem here?
EDIT
I understood that using withUnsafe*** I can get the pointer to the data, but what to do if my method has 2 params, would it looks like this
withUnsafePointer(to: myObjFirst) {
pFirst in
withUnsafePointer(to: myObjSecond) {
pSecond in
foo(pFirst, pSecond)
}
}
The & syntax does not mean "the address of" or "pointer to" like in C. In Swift, it is an in-out expression.
These can be used to create implicit pointer conversions as a convenience, and that can seem like C's "pointer to" meaning, but it has very different rules and behaviors. For example, there is no promise that obj even has an address. It may be a tagged pointer. Passing it via an in-out expression may allocate memory and copy the value to make the call possible. Similarly, when passing a "pointer to an array," Swift will actually pass a pointer to a contiguous block of values (which may have been copied to make them contiguous) which is not the same as the actual Array struct.
It is not meaningful to say var pointer = &obj. There is no in-out reference there.
There is no general way to take long-lived pointers to objects in Swift without allocating your own memory (and this is rare). The memory model doesn't promise the kinds of lifetimes you'd need to make that sensible. If your code did compile the way you expect it to, the call to foo(pointer) would still be invalid because there's no promise that obj exists at that point and the pointer could be dangling. (There are no references to obj after the first line, so Swift can and often will destroy it, even though it's still "in scope.")
The foo(&obj) syntax is basically a shorthand for:
withUnsafePointer(to: obj) { foo($0) }
It exists to make it easier to call C functions, but it doesn't mean that Swift pointers are anything like C pointers.
For much more on Swift pointers, see Safely manage pointers in Swift from WWDC 2020.

Why is the "new" keyword not necessary in Swift?

Why is the new keyword not necessary in Swift?
In other languages such as Java or C#, new is necessary to allocate memory for a each new object.
Ex.
(Foo) foo = new Foo()
However in swift, it's
(var) foo = Foo()
If Swift has built in garbage collection/memory allocation, is new implicit, or is it simply not used. If the latter, why/what replaces it?
new is just a language construct that says I want to initialize and create a new Foo. If the compiler is smart enough to determine that that's what you want to do from the context, why be verbose about it? The bottom line is that there's really no functional difference between:
[[Foo alloc] init] - Objective C
[Foo new] - Objective C
new Foo() - C/C++/Java
Foo() - Swift
Also note that in C++, you can use the following to generate a stack-based object:
Foo foo();
ARC, reference counting, garbage collection, explicit delete, are all just mechanisms for reclaiming memory used by objects that are no longer needed, and really have no bearing on the language syntax necessary to create an object in the first place.
Don't get hung up on syntax, learn to recognize constructs and operations, and then attach syntax to constructs and you're 90% of the way to knowing every programming language out there.
For heap-allocated/reference types (classes), Swift utilizes Automatic Reference Counting: rather than requiring explicit calls to delete, memory is deallocated when the last "strong" reference to it disappears. var foo = Foo() or let foo = Foo() allocates and initializes an instance of the Foo class, and creates a local variable with a strong reference to it. When this variable goes out of scope, if no other references have been made, the object is deallocated.
From The Swift Programming Language:
Every time you create a new instance of a class, ARC allocates a chunk of memory to store information about that instance. This memory holds information about the type of the instance, together with the values of any stored properties associated with that instance.
Additionally, when an instance is no longer needed, ARC frees up the memory used by that instance so that the memory can be used for other purposes instead. This ensures that class instances do not take up space in memory when they are no longer needed.
You can also read about the initialization sequence, i.e. the interactions between properties and custom inits in a class hierarchy.

If a function returns an UnsafeMutablePointer is it our responsibility to destroy and dealloc?

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 { /**/}

Objective C, Memory Management

1) What is the reason for the use of retain?
For example, in a setter method:
- (void) setCount: (int) input {
[intCount autorelease];
intCount = [input retain];
}
2) the autorelease-Method: Is it deleting an old object or preparing the new one?
3) Why the retain-method is called at the input-object?
Would
intCount = input;
be wrong?
And why?
Retain is used to increment the retainCount of an object. NSObjects have a property called retainCount which maintains a count on the number of references that are currently held on an object. When the retainCount of an object reaches 0, the object can be released from memory. Effectively this prevents an object from being released from memory if it's still in use elsewhere.
The autorelease method does not delete an old object and does not prepare the new object. It is effectively a pre-emptive call to release the object (autorelease is much more complicated than that and you should read up on it in the Memory Management Guide.)
In your case intCount = input wouldn't be wrong because you're working with a primative. However if input were an object then you'd need to be calling retain on it. In fact you don't even need to be writing your own getters/setters for primatives (or objects), but instead should be using Declared Properties. In fact you're almost always better off using Declared Properties and if you do want to roll your own, get to know the pitfalls of doing so first.
I recommend you read this. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html
The answers to your questions have been answered fairly well so let me just add that if you can use garbage collection you should. It makes everything so much easier. It isn't a panacea and you still should learn to use the retain/release mechanism but unless you are dealing in some high volume memory calls, creating and deleting lots of objects, then just use garbage collection.
It can be found under Project | Edit Project Settings | Build
Then just search for "garbage" and you'll see it.
If you are doing iOS development and cannot use garbage collection I apologize for giving unhelpful information but it still stands for non-iOS development.
To answer ur question specifically:
1). the use of retain is to declare the ownership of an object. In this case, intCount retains the ownership of input, in case the input got released somewhere else, u can still use the intCount.
2). the autorelease of intCount is to relinquish the ownership of the old value. That avoid the memory leak of the old value. If u don't release the old value, and u assign a new value to this pointer, the old object will always be there and never got released, which will cause the memory leak.
3). if u don't retain the input, and the parameter of input got released somewhere else. then if nowhere else retain this object, it will get freed. So u can't use intCount as well. That's why u need to retain it or copy it.
But i think if u do intCount = input; it should be fine. Because int is not an object, it's just a type. So I think the whole method is okay to be written like this:
- (void) setCount: (int) input {
intCount = input;
}
But if its a pointer, u should not assign the new value to the old one directly.

Memory management about CGPoint

refer to CGPointMake explaination needed?
Correct me if I am wrong, in the implementation of CGPointMake, CGPoint p; declare a local variable of a struct, which should should be freed after leaving the scope. But why the function can return the value without risk?
Anyway, assume that implementation of CGPointMake is correct, should I free the CGPoint that created by CGPointMake?
It doesn't need to be freed, because it never lived on the heap. Only heap-allocated memory needs to be freed. Memory that is allocated on the stack (as is done in CGPointMake()) will be cleaned up automatically after the method/function exists.
The function can return a point because the compiler sees "Aha, this function wants to return a struct, which is sizeof(CGPoint) bytes big, so I'll make sure that there's enough space in the return value memory slot for something that big." Then as the function exits, the return value is copied in to the return memory slot, the function exits, and the value in the return slot is copied over to its new destination.
The function can return a CGPoint because the struct is "small enough" to be returned directly from a function. You're not returning a pointer, you're returning the whole thing directly. Same with methods that take CGPoints as parameters-- you can pass the whole thing by value directly.
As Dave notes, CGPoints aren't objects, they're just structs. CGPointMake doesn't "allocate" memory. It's just a function that returns a struct set up with the right sizes, which you then usually capture into a local on your own stack or pass along or whatever.
Like any other primitive type (int, float, or other struct), it doesn't need to be freed when it goes out of scope.
(Note: many architectures/compilers/"application binary interface"s have optimizations and size limits regarding the size of a thing used as an argument or return value. In this case, a CGPoint could actually fit entirely inside one 64-bit register (2x 32-bit floats) which makes it no more heavyweight than returning an int. But the compiler can also do other tricks as far as copying in and out larger structures e.g. CGRect.)