I have a few questions regarding dynamic variables and pointers so I can understand them better.
Are dynamic variables automatically disposed of when their scope expires? If not, then what happens?
Is the value of a pointer a memory address? If not, then what are they?
It's important to understand that there two complete separate, discreet, independent "things" that you are asking about.
A pointer to an object that was created in dynamic scope (i.e. with the new statement).
And the object itself, that the pointer is pointing to.
It's important for you two separate the two in your mind, and consider them as independent entities, in of themselves. Insofar as the actual pointer itself, its lifetime and scope are no different than any other object's. When it goes out of scope it gets destroyed.
But this has no effect on the object the pointer was pointing to. Only delete destroys the object. If there's some other pointer, that's still in scope, that points to the same object, you can use that pointer for the requisite delete.
Otherwise you end up with a memory leak.
And the value of the pointer is, for all practical purposes, a memory address. This is not specified in any form or fashion in the C++ standard, which defines pointers and objects in dynamic scope in terms of how their behavior is specified. However on all run-of-the-mill operating systems you'll see a memory address in the pointer.
It's also important to understand that since a pointer is an independent object, a pointer doesn't have to point to an object in dynamic scope. There are many pointers that don't. It's not a trivial task to keep track of all objects, all pointers, and to figure out which ones need to be deleted properly. Modern C++ has additional classes and templates that will help you do that, which you'll learn about in due time.
Related
According to Warford's "Computer Systems" (4th ed), "When you declare a global or local variable, you specify its type. For example, you can specify the type to be an integer, or a character, or an array. Similarly, when you declare a pointer, you must declare that it points to some type. The pointer itself can be global or local. The value to which it points, however, resides in the heap and is neither global nor local."
I know that you can create local variables in the stack, global variables in a fixed location, and dynamically allocated variables in the heap. Can pointers only point to dynamically allocated variables then? Why can't a pointer point to global or local variables?
Thanks
The value to which it points, however, resides in the heap and is neither global nor local.
That is incorrect.
Can pointers only point to dynamically allocated variables then?
No.
Why can't a pointer point to global or local variables?
They sure can.
You might want to read the book more carefully to see whether the statement in book was made with some additional context. If not, it's time to abandon the book and learn from a different one.
The pointer point to the place in memory where the variable is located. I don't think you should care about where it is. You can make a pointer to absolutely any variable even outside of your program (however this is dangerous and may also crash your app). Pointer is just a number, address in memory. There are many cases where you point to global/local variable. For example if you want to pass class/array to some function.
A pointer can point to local variables or global variables (or fields inside them). But you might prefer references in that case.
A pointer can also point to memory obtained by some ad-hoc mechanism. For instance, the ::operator new on Linux would indirectly call mmap(2) (or similar system calls) which grows the virtual address space of your process. Or in some embedded processors you have special primitives to get some memory (e.g. switch memory banks), etc...
A pointer can also point to some address outside of your virtual address space. Then dereferencing it is undefined behavior and often gives a segmentation fault.
However, it is often (but not always) considered bad taste to point to local or global data. It is often simpler to code with the convention that pointers should be to heap allocated memory. Read also about smart pointers (notably std::shared_ptr) and reference counting.
(there are some excellent reasons to use pointers to local data on the call stack or to global data, but that should be done with caution and care; I leave you to find out more about them, perhaps by studying existing C++ source code - e.g. of free software)
Read also about memory leaks and dangling pointers. You should avoid both of them. On Linux and POSIX systems, learn about valgrind (a tool to help hunting memory related bugs).
The terminology and concepts of garbage collection are useful to know.
A common style might be (for pointers stored in fields of classes or structures) to allocate memory for them with new in constructors and to release with delete in destructors.
Pointers can point to any object, such that statement "The value to which it points, however, resides in the heap" is at least incomplete, actually wrong. A pointer can point to any object, regardless of whether it resides on a "stack", on a "heap" or on same "fixed" memory, and regardless of whether it is a "global variable" or a "local variable". Note that all these terms are imprecise and not even used in the standard in the context of objects or pointers. The standard just talks about storage duration of objects (automatic, static, dynamic), and about the scope (i.e. visibility) of the variable name (block, function, namespace, global namespace,...).
So the only important thing is that a pointer can point to any object, regardless of its storage duration, but it must not be "used" (i.e. dereferenced) before the lifetime of the object it points to has begun or after the lifetime has ended. Otherwise, the behaviour of your program is undefined.
BTW: regardless of how old your book is, there has not been any C++ standard where the statement "points always to the heap" has been true.
In C++, this pointer get passed to method as a hidden argument which actually points to current object, but where 'this' pointer stored in memory... in stack, heap, data where?
The standard doesn't specify where the this pointer is stored.
When it's passed to a member function in a call of that function, some compilers pass it in a register, and others pass it on the stack. It can also depend on the compiler options.
About the only thing you can be sure of is that this is an rvalue of basic type, so you can't take its address.
It wasn't always that way.
In pre-standard C++ you could assign to this, e.g. in order to indicate constructor failure. This was before exceptions were introduced. The modern standard way of indicating construction failure is to throw an exception, which guarantees an orderly cleanup (if not foiled by the user's code, such as the infamous MFC placement new bug).
The this pointer is allocated on the stack of your class functions (or sometimes a register).
This is however not likely the question you are actually asking.
In C++, this is "simply" a pointer to the current object. It allows you to access object-specific data.
For example, when code in a class has the following snippet:
this->temperature = 40.0f;
it sets the temperature for whatever object is being acted upon (assuming temperature is not a class-level static, shared amongst all objects of the class).
The this pointer itself doesn't have to be allocated (in terms of dynamic memory), it depends entirely on how it's all handled under the covers, something the standard doesn't actually mandate (the standard tends to focus more on behaviour than internals).
There are any number of places it could be: on the stack, at a specific memory location, in a register, and so on. All you have to concern yourself with is its behaviour which is basically how you use it to get access to the object.
What this points to is the object itself and it's usually allocated with new for dynamic allocation, or on the stack.
The this pointer is in the object itself*. Sort of. It is the memory location of the object.
If the object is on the stack, the this pointer is on the stack.
If the object is on the heap, the this pointer is on the heap.
Bottom line, it's nothing you need to worry about.
*[UPDATE] Let me backpedal/clarify/correct my answer. The physical this pointer is not in the object.
I would conclude the this pointer is derived by the compiler and is simply the address of the object which is stored in the symbol table. Semantically, it is inside the object but that was not what the OP was asking.
Here is the memory layout of 3 variables on the stack. The middle one is an object. You can see it holds it's one variable and nothing else:
Ok, so I'm very new at C++ programming, and I've been looking around for a couple days for a decisive answer for this. WHEN should I declare member variables on the heap vs. the stack? Most of the answers that I've found have dealt with other issues, but I want to know when it is best to use the heap for member variables and why it is better to heap the members instead of stacking them.
There are two important concepts to grasp first:
One should avoid thinking in terms of "heap" and "stack". Those are implementation details of your compiler/platform, not of the language.1 Instead, think in terms of object lifetimes: should the object's lifetime correspond to that of its "parent", or should it outlive it? If you need the latter, then you'll need to use new (directly or indirectly) to dynamically allocate an object.
Member variables always have the same lifetime as their parent. The member variable may be a pointer, and the object it points to may well have an independent lifetime. But the pointed-to object is not a member variable.
However, there is no general answer to your question. Crudely speaking, don't dynamically allocate unless there is a good reason to. As I hinted above, these reasons usually correspond to situations where the lifetime needs to differ from its "parent".
1. Indeed, the C++ standard doesn't really talk about "heap" and "stack". They're important to consider when optimising or generally thinking about performance, but they're mostly irrelevant from a program-functionality point of view.
Member variables are members of the class itself. They are neither on
the heap nor on the stack, or rather, they are where ever the class
itself is.
There are very few reasons to add a level of indirection, and allocate a
member separately on the heap: polymorphism (if the type of the member
is not always the same) is by far the most common.
To get some terminology straight: What you call a heap and stack describe the lifetime of objects. The first means that the lifetime is dynamic, the second automatic and the third (which you don't mention) is static.
Usually you will need dynamic lifetime of an object when it should outlive the scope it was created in. Another common case is when you want it to be shared across different parent objects. Also, dynamic lifetime is also necessary when you work with a design that is heavyly object-oriented (uses a lot of polymorphism, doesn't use values), e.g. Qt.
An idiom that requires dynamic lifetimes is the pimpl-idiom.
Most generic-programming libraries are more focused towards value and value-semantics, so you won't use dynamic binding that much and automatic lifetimes become a lot more common.
There are also some examples where dynamic allocation is required for more implementation specific reasons:
dynamically sized objects (containers)
handling incomplete types (see pimpl-idiom)
easy nullability of a type
All of those are just general guidelines and it has to be decided on a case by case basis. In general, prefer automatic objects over dynamic ones.
The stack refers to the call stack. Function calls, return addresses, parameters, and local variables are kept on the call stack. You use stack memory whenever you pass a parameter or create a local variable. The stack has only temporary storage. Once the current function goes out of scope, you no longer have access to any variables for parameters.
The heap is a large pool of memory used for dynamic allocation. When you use the new operator to allocate memory, this memory is assigned from the heap. You want to allocate heap memory when you are creating objects that you don't want to lose after the current function terminates (loses scope). Objects are stored in the heap until the space is deallocated with delete or free().
Consider this example:
You implement a linked list which has a field member head of class node.
Each node has a field member next. If this member of the type Node and not Node* the size of every Node would depend on the number of the nodes after it in the chain.
For example, if you have 100 nodes in your list your head member will be huge. Because it holds the next node inside itself so it needs to have enough size to hold it and next holds the next and so on. So the head has to have enough space to hold in it 99 nodes the next 98 and so on...
You want to avoid that so in this case it's better to have pointer to to next node in each Node rather than the next node itself.
I'm having really hard time to learn nullifying the "other" object, I've just read the whole big article about move semantics here and I'm disappointed because it does not cover nullifying.
Please explain me do we really need to nullify all the members of "other" or just pointers that are pointing to dynamically allocated memory?
Why would we care about nullifying the members (of other object) that are not on the heap? any good reason?
After you've moved from the object, its destructor is still going to get called once it's cleaned up. This means that it needs to know whether or not it should free resources it owns, and hence they need to be nullified (or whatever you call it!) so pointers don't get double-deleted etc.
You need to leave the object that has been moved from in a valid state. I take this to mean that no use of that object should result in undefined behaviour. In practice, that means not leaving pointers pointing to released memory. I can imagine there could be other scenarios, such as if the object is holding onto any other resources (open sockets, files, whatever).
I dont know if you actually mean this in case of just constructor or even in case of normal pointers allocated dynamically .
But Nullyfing a pointer saves it from being termed as Dangling pointer as it points to null after the memory allocated for it is free. Further use of these pointers and dereferencing those will lead to core dumps which are easy to locate than when not done so . Not doing so can give unexpected results and lead to core dumps hard to find and even data corruption.
In short You should take care of only nullyfing the pointer.
As usual, "it depends".
The moved-from object will still have to be destroyed, or possibly assigned a new value. You have to leave it in a state where these operations will work.
If you have "stolen" pointers to dynamic data, you will probably have to assign null to the original pointers so they can be deleted. If one of the integer members holds the size of the object pointed to, you might have to zero that (to be consistent with the null pointer). Other values can possibly be left as they are.
I want to use the actual pointer address (not marked volatile) to an object to uniquely identify the object.
Is this a bad thing to do? In general does system memory management move the objects and hence it's address about or is the pointer stable?
Thanks
Your pointer is guaranteed to remain stable for the life of the object to which it points, unless you do something to break it. The OS does indeed move things around in memory, but that's physical memory - the virtual memory space the OS presents to your process will keep things at the same addresses.
In C, the address of an object is constant for its lifetime. Note that per the C standard, realloc does not "move" an object; it allocates a new object with the same contents (for the shorter of the old and new length) and, if successful, frees the old object.
Pointers are stable, however, you should be using pointers correctly other wise you code will be unstable.
A pointer will be valid until the moment an object dies, once an object dies then you will have what is known as a Dangling Pointer.
There are many ways to avoid dangling pointers, some of them are very advanced topics. For example, you could use "Handles" but that is more sophisticated approach and would require a different memory management than what is default.
The language you are using also matters for the way a pointer can be invalidated. You have your question tagged as C, C++ and Objective-C. In C, your pointer can be invalidated by a malloc and realloc, where in C++ your pointer can be invalidated by delete.
I highly suggest reading more on pointers if you are first being introduced, such as this article.
I also suggest reading more into std::shared_ptr.
iOS memory management does not move the object around. If you have a pointer to an object it is valid for the life of the object.
In your question you refer to a "pointer address". However I assume you mean a pointer to the object. Otherwise the answer to this question becomes more complicated.
A pointer to an object is valid until the object dies (stable).
Using pointers for identification has its uses, but may not be the best thing to do.