views:

300

answers:

4

I had a couple questions related to this: http://stackoverflow.com/questions/2035994/asterisk-usage-in-objective-c

NSArray array; in a local scope would be an object "allocated" on the stack. NSArray *array; indicates an object backed by a hunk of memory, typically allocated from the heap.

How do you know when something is allocated on the stack and on the heap? Are all local variables on the stack and are all pointers on the heap?

Because you aren't dereferencing the pointer to the object and that pointer to the object is critical within the method implementation itself. When you say...

Huh

+4  A: 

The * is the dereference operator for C, C++ and Objective-C. Understanding the dereference operator, and memory management in general is far broader than Objective-C. This is a fundamental skill for any C/C++/Objective-C developer. Have a look at the multitude of intro C tutorials on the net to learn more.

Edit: any tutorial on c pointers will do. Such as this http://home.netcom.com/~tjensen/ptr/pointers.htm

darren
The * in a declaration is not an operator; it's part of the declaration.
Peter Hosey
x = *y means get the value stored at the address held by y. We are not declaring anything here. It is a dereference operator.
darren
The asterisk in the quote in the question is in a declaration (`NSArray *array;`).
Peter Hosey
+2  A: 

In Cocoa, you'll never use stack allocated objects; ALL objects will be prefaced with a * (remember that the type "id"is really another word for "pointer to SOME object") and created on the heap.

You'll always have this:

NSArray     *myArray;

and never this:

NSArray     myArray;

You can ignore the second chunk, since you're always dereferencing the pointer.

Ben Gottlieb
That's not true at all. `NSRect` and `NSPoint` etc belong to Cocoa and they can be allocated on the stack. Edit: I think I misunderstood when you used the term 'object', by 'object' you mean Objective-C object, right?
dreamlax
dreamlax: to be fair, those aren't objects. ben states that you'll never use stack allocated OBJECTS.
Kenny Winker
They're not objects though, so this is correct.
darren
I guess my main question is the difference between the stack and the heap then...any good resources for that?
Rebecca Morgan
yehnan
+5  A: 

How do you know when something is allocated on the stack and on the heap? Are all local variables on the stack …

It doesn't matter. The stack and heap are implementation details; the C and Objective-C languages do not know about them, and you should generally not have any reason to care whether something is on the stack or the heap.

On Mac OS X, local variables are on the stack. But, for almost all purposes, this is of no consequence. Don't worry about it.

… and are all pointers on the heap?

No. Pointers are memory addresses; that's all.

Pointer variables can be anywhere any other variables can, which is to say, anywhere (subject to implementation-defined limitations that you needn't care about, as noted above).

See my pointer tutorial for more information.

Because you aren't dereferencing the pointer to the object and that pointer to the object is critical within the method implementation itself. When you say...

Huh

A pointer is a memory address. As such, it refers to the memory at that address. Dereferencing the pointer is accessing that memory.

You never, ever directly access the memory a Cocoa object takes up. You only send it messages, to either ask it questions or tell it to do things. Thus, you never dereference the pointer.

“…that pointer to the object is critical within the method implementation itself.” means that the object, in its method implementations, will need its own pointer. It's only possible to send a message to a pointer to an object (this detail is usually elided). If you somehow pulled this off, the receiver of the message (that is, the object you messaged) would not have its own pointer.

Suppose it were possible to send a message to a dereferenced object. The norm is still to send messages to pointers to objects, so in all likelihood, the object will still need that pointer to itself—making that hypothetical ability to message a dereferenced object useless.

Since it's useless, they left it out entirely. The object will need its own pointer (the pointer is critical to the object's method implementations), so you can only send a message to its pointer.

Peter Hosey
Thanks for the great explanation Peter. You should be a teacher or something :PSo is it correct to say the following:1) As bbum mentioned, Objective-C doesn't support variables on the stack. When you call alloc, it just calls malloc, which means you *have* to have a pointer to it since it just returns a block of memory.2) Every Objective-C method needs a pointer to the object. This is just how its implemented.
Rebecca Morgan
1. That's not what bbum said. He said Objective-C doesn't support Objective-C objects on the stack, which is true. Variables can be on the stack (if a stack exists, which it does in current Mac OS X). What `alloc` does, any more specifically than “allocate memory for an object and return the pointer to it”, is an implementation detail. 2. It's not “just how it's implemented”, it's the only way that makes sense. The object cannot do anything with itself without its own pointer, so there is no reason for you to be able to send the object a message without the pointer.
Peter Hosey
So I guess my next question is: why does an object needs its own pointer?
Rebecca Morgan
To send itself messages (since you can only message a pointer) and to access its own instance variables.
Peter Hosey
Elaborating a bit: In order for an object to send a message to itself, it must have `self`, which is a pointer. Without that, it cannot send a message to itself. And accessing one's own instance variables is an implicit `self->`; again, without the `self` pointer, that's impossible.
Peter Hosey
+2  A: 

Hope these naive toy examples can help you.

In C, in a function,

int x; // x is a variable of type int in stack
int *xp; // xp is a variable of type int * (pointer to int) in stack
int *xp2 = (int *) malloc(sizeof(int)); // xp2 is a variable in stack, it points to a memory location(size is of int) in heap
xp = &x; // xp can point to x
xp = xp2; // xp can also point to what xp2 points to
free(xp2); // now xp and xp2 point to a freed memory, BAD to use xp and xp2 now.
int **y; // y is a variable in stack, type is int **
y = (int **) malloc(sizeof(int *)); // allocate a piece of memory in heap, to hold a pointer to int(int *)
*y = (int *) malloc(sizeof(int)); // allocate a piece of memory in heap, to hold an int
**y = 100; // now we can use it
free(*y);
free(y);

In C++, in a function or member function(method),

SomeClass a1; // a1 is an object of type SomeClass in stack
SomeClass *a2 = new SomeClass(); // a2 is a pointer(in stack) pointing to an object(of type SomeClass) located in heap
delete a2;

So in C++, objects can exist in stack or heap

In Java, in a function or method,

SomeClass b1; // b1 is just a reference, no object exists yet
b1 = new SomeClass(); // in java, objects can only exist in heap
int x; // however, primitive types are in stack, 

In Objective-C, in a function or method,

SomeClass c1; // you can't do this.
SomeClass *c2 = [[SomeClass alloca] init]; // c1 is a pointer in stack, pointing to an object in heap
[c2 release];
yehnan