3

I have a basic understanding of what a "stack" and "heap" are. You use a stack to store items in memory that should be read and/or removed in a last-in-first-read/removed manner. To steal another example from someone else's Website, you use it to perform arithmetic operations involving PEMDAS. You also use a stack to store return addresses for functions. Like a heap, the CPU uses a pointer to find the item to be read and/or removed.

You use a heap when you don't need the computer to store objects in a sequential order in memory.

My question is, what's the deal with the * pointer in Objective-C? Local variables in a method are going to get deallocated when the method's done anyway, so why not just use the stack instead?

I'm going to go out on a limb here and say that the short answer is that because stacks have a limited memory, Objective-C wants to keep its stack usage to a minimum.

5
  • What if you want to allocate space for a variable which lasts longer than the current method?
    – Sam Dufel
    Jul 31, 2015 at 19:58
  • While its in the Java context, many of the points I make in this answer are applicable to Objective C also.
    – user40980
    Jul 31, 2015 at 19:59
  • @SamDufel: Allocating space for a variable on the heap... that reads wrong. Unless you are using cactus-stacks, or some other way of allocating individual activation-records on the heap. Jul 31, 2015 at 20:10
  • @Deduplicator - I think you misquoted me; I didn't mention the heap.
    – Sam Dufel
    Jul 31, 2015 at 21:00
  • @SamDufel: I know you didn't say heap. I wanted to highlight that variable and dynamically allocated are at cross-purposes. If you had said object... Jul 31, 2015 at 21:02

3 Answers 3

4

The main reason is that just because you're done with a local reference to an object doesn't mean you're finished with the object itself.

For example, if your function creates an object and adds it to a pre-existing collection that belongs to a broader scope, then the object has to be on the heap; anything on the stack gets trashed after the function returns, but the collection (and all the objects it contains) is still valid.

This is just one of many scenarios where you would need to keep an object around after the function that first created it returns. (Also consider the case of a function whose return value is a newly-created object, for example...) In all such cases, you need to keep the value in a non-ephemeral portion of memory.

Some compilers can perform a special trick known as escape analysis, where they analyze the object's lifetime and if they can prove that the object will not outlive its function, they rewrite the code that creates it to place it on the stack, making creation and cleanup cheaper. But this is a pretty advanced (and very difficult) piece of analysis; it's much simpler to just all have objects allocated on the heap by default.

3
  • 1
    If the object is sufficiently small, it may not even be allocated on the stack and instead live entirely in registers.
    – user40980
    Jul 31, 2015 at 20:06
  • Indeed, Escape Analysis is not merely "pretty advanced (and very difficult)", it is actually equivalent to solving the Halting Problem. Doing Escape Detection at runtime, though, is not: you just allocate on the stack, observe the references, and if one escapes, you move the object to the heap and patch the references. This is much easier with dynamic compilation, though, with AOT compilation, it would more or less require binary patching of the running program. Not fun. (This is often the case: statically deciding a property is equivalent to the HP, but at runtime, you can just look.) Jul 31, 2015 at 23:18
  • By "collection" I assume you mean an NSArray, NSSet, etc, am I right? And what you're saying is that just because an object or method has no need to retain a reference to an object doesn't mean other objects or methods won't, am I right?
    – moonman239
    Aug 1, 2015 at 1:09
2

To go into a little bit of history, it was not always the case that stack based objects were forbidden in Objective-C. Michael Rutman told me (in 2009) that this happened in NeXTSTEP version 2.0 back in 1990.

"This was the release where zones were introduced, new was replaced with alloc/init, and stack based objects were no longer allowed."

I see from my copy of Brad Cox's "Object Oriented Programming", dated 1987, that alloc and init don't exist and new is used to allocate arrays.

Zones were introduced to allow the programmer to specify which region of memory was to be used for the object; this would imply (although to know for sure I'd have to bother Michael Rutman or Brad Cox) that the reason they were no longer simply put on the stack was to allow (or force) the programmer to think about where they were putting their objects.

alloc had a sister function, allocWithZone. alloc would use a default zone, while allocWithZone would allow the programmer to specify the zone to use for this object. Faster memory for some, slower memory for others, group things together as needed.

The GNU Step manual, http://andrewd.ces.clemson.edu/courses/cpsc102/notes/GNUStep-manual.pdf , in section 3.1.2, discusses it and states that it was for performance reasons.

So while the reason for it today might be as people discuss in other answers, this would suggest that originally it was about giving programmers control for performance reasons. For example, it allowed programmers to group together objects that would be used together frequently, to cut down on paging and the like.

1

In Objective-C, objects are reference counted. An object goes away when there is no reference to it anymore. On the other hand, objects on the stack go away when the function call ends. Can you see the problem? If the last reference goes away before the function call ends, you waste memory. If the function call ends while there are still references to the object, you have a much more serious problem.

Now you could have objects both on the stack and on the heap, as C++ does. Is it worth it? There is added code complexity, and what do you actually gain? Memory allocation on the heap is fast - after all, if everything is allocated on the heap, you have some rather strong motivation to make it fast.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.