Memory management about CGPoint - iphone

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.)

Related

ARC doesn't apply to struct and enum, how are they deallocated in Swift

Since ARC doesn't apply to struct and enum, then how are they deallocated from the memory? I have to get stuck when it asked in the interviews and try to find the correct answer but can't find much info on it googling. I know swift is smart at handling value types. But how?
The memory management of objects (instances of classes) is relatively difficult, because objects can outlive a function call, the life of other objects, or even the life of the threads that allocated them. They're independent entities on the heap, that need book keeping to make sure they're freed once they're not needed (once they're no longer referenced from any other threads/objects, they're unreachable, thus can't possible be needed, so are safe to delete).
On the other hand, structs and enums just have their instances stored inline:
If they're declared as a global variable, they're stored in the program text.
If they're declared as a local variable, they're allocated on the stack (or in registers, but never mind that).
If they're allocated as a property of another object, they're just
stored directly inline within that object.
They're only ever deleted
by virtue of their containing context being deallocated, such as when
a function returns, or when an object is deallocated.

When constructing a Swift UnsafeMutablePointer manually, is destroy/dealloc obligatory after alloc?

Let's say that in Swift I construct a C array manually and pass it, like this:
override func drawRect(rect: CGRect) {
let c = UIGraphicsGetCurrentContext()
var arr = UnsafeMutablePointer<CGPoint>.alloc(4)
arr[0] = CGPoint(x:0,y:0)
arr[1] = CGPoint(x:50,y:50)
arr[2] = CGPoint(x:50,y:50)
arr[3] = CGPoint(x:0,y:100)
CGContextStrokeLineSegments(c, arr, 4)
}
(I know I don't have to do that, but just bear with me.) If I don't call destroy and/or dealloc on this UnsafeMutablePointer, am I leaking the memory for four CGPoints?
The documentation for UnsafeMutablePointer is pretty clear:
/// This type provides no automated
/// memory management, and therefore the user must take care to allocate
/// and free memory appropriately.
So if you allocate but don’t deallocate, you will leak memory. There’s no auto-deallocation on destruction of the pointer object.
Re whether you should destroy before deallocating, it’s also pretty clear:
/// 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.
But bear in mind you can transition back and forth between these states. So after allocating then initializing then de-initialzing (aka destroying) the objects, the memory is no longer in the “initialized” state, so you can either re-initialize or deallocate it. You can also allocate, then deallocate, without ever initializing.
And when calling dealloc:
/// Deallocate `num` objects.
...
/// Precondition: the memory is not initialized.
///
/// Postcondition: the memory has been deallocated.
Therefore you must call destroy on any initialized objects before calling dealloc. You are probably right in that since something like CGPoint is totally inert (just a struct of two floating point nums) it probably doesn’t do any harm not to call destroy before you call dealloc but you can’t be certain without knowing the implementation (of both the pointer struct and the compiler probably, since the standard lib is a quasi-part of the language there could be some baked-in optimizations), and generally, it’s just not a good habit to get into. Sooner or later you’ll forget to destroy a String, and then you’ll be sorry.
(none of this accounts for the move operations btw which combine initializing new memory with destroying old memory)
If you were hoping for some kind of automated self-cleanup of memory by UnsafePointer, I don’t think this would be possible as a) it’s a struct, so can’t implement a deinit to auto-deallocate when going out of scope, and b) it doesn’t track it’s own size – you have to track how much you allocate, and supply that back explicitly in the call to deallocate.
There is something in the standard library that does auto-deallocate memory without you having to do it yourself – HeapBufferStorage, the one and only class in the standard library. Presumably it’s a class specifically to benefit from an implementation of deinit. There’s also HeapBuffer to manage it with, and this has a handy isUniquelyReferenced() function that allows you to tell if it’s been copied (even though it’s a struct) and so would allow you to implement copy-on-write capability similar to arrays and strings.
In Swift 2 UnsafeMutablePointer can be made a bit less frustrating by pairing alloc/dealloc with the new defer keyword:
let ptr = UnsafeMutablePointer<T>.alloc(1)
defer { ptr.dealloc(1) }
This is for others like me who found this question/answer thread by searching CGContextStrokeLineSegments. If your purpose is to call this function in Swift, you don't have to construct a C array pointer even though the function's second parameter is an UnsafeMutablePointer. You can directly pass a Swift array into it, even a non-mutable one, instead of a C pointer with its allocation and deallocation. For example:
override func drawRect(rect: CGRect) {
if let c = UIGraphicsGetCurrentContext()
{
let arr = [CGPoint(x:0,y:0), CGPoint(x:50,y:50), CGPoint(x:50,y:50), CGPoint(x:0,y:100)]
CGContextStrokeLineSegments(c, arr, 4)
}
}

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

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

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

Raw data types Vs Objects in Objective C

Something I've been wondering for a while. I know that in order to free up memory, objects (Such as NSMutableArray) have to be released, but raw data types (Such as int) don't. My question is, at what point does the space in memory that an int is occupying become free?
For example, a class "myClass" has an iVar "int a"
"a" holds the value some integer value.
When "myClass" is deallocated, does the space in memory that was holding the value for "a" become free straight away?
Thanks in advance.
For class ivars, the memory is freed when the object instance is deallocated - upon the last [release] call. For local int (and other primitive) variables, when the function returns. For global and static variables, when the process quits.
Also, you can allocate int's dynamically with malloc(). Then it's freed when you call free().
"a" is included in the memory allocated in "myClass". In other words, when myClass is deallocated, "a" is gone right along with it.
An Objective C object is similar to a pointer to a malloc'd C structure (containing both declared and a few hidden instance variables). When an object is released, the entire C structure memory block, including all internal ivar storage, is free'd (as well as any other dealloc housekeeping required).