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:
Related
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.
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.
When we create objects from a type library for instance
SomeClassPtr some_obj(__uuidof(SomeImplementation));
is some_obj created on a heap or stack ? I mean is it like
SomeClassPtr *some_obj = new SomeImplementation();
Wrong way to think about it. Not the stack.
But that's where the guessing ends. This COM object could live in a different process. Or on a machine half-way around the world. All you got is an interface pointer, what it points to you don't know. Could be the actual object allocated on the heap. Could be a proxy that talks to a stub located somewhere else. Anywhere else. That's a feature, avoid caring about it.
In this case, your "pointer" (SomeClassPtr) is pointing to a block of memory which will be heap allocated.
However, it's not necessarily performing the heap allocation, as it's actually a reference counted type which handles the allocation and deallocation (via IUnknown::AddRef and IUnknown::Release). This means it may be acquiring and incrementing the reference count of an object which was previously allocated, depending on the type stored in the COM pointer.
Actually, it's a little wierder than that.
Strictly speaking, the first example is a stack variable, and the second example is a heap variable (assuming new hasnt been overridden.
The wierd part happens because, by the nature of COM, you don't get know what or where or if (if the result is an AddRef, there might not be, for example) any other allocation happens; in particular, for allocations that need to cross thread/process boundaries (which will always be the case for out of process servers), the default implementation of IMalloc::Alloc (CoTaskMemAlloc()) is to allocate from one of the heaps of the process in which the COM object is actually created/instantiated.
As pointed out elsewhere, that's a feature; you shouldn't need to care.
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.
Can I check if an object (passed by pointer or reference) is dynamically allocated?
Example:
T t;
T* pt = new T();
is_tmp(&t); // false
is_tmp(pt); // true
Context
I perfectly realise this smells like bad design, and as a matter of fact it is, but I am trying to extend code I cannot (or should not) modify (of course I blame code that isn't mine ;) ). It calls a method (which I can override) that will delete the passed object among other things that are only applicable to dynamically allocated objects. Now, I want to check whether I have something that is okay to be deleted or if it is a temporary.
I will never pass a global (or static) variable, so I leave this undefined, here.
Not portably. Under Solaris or Linux on a PC (at least 32 bit Linux),
the stack is at the very top of available memory, so you can compare the
address passed in to the address of a local variable: if the address
passed in is higher than that of the local variable, the object it
points to is either a local variable or a temporary, or a part of a
local variable or temporary. This technique, however, invokes undefined
behavior right and left—it just happens to work on the two
platforms I mention (and will probably work on all platforms where the
stack is at the top of available memory and grows down).
FWIW: you can also check for statics on these machines. All statics are
at the bottom of memory, and the linker inserts a symbol end at the
end of them. So declare an external data (of any type) with this name,
and compare the address with it.
With regards to possibly deleting the object, however... just knowing
that the object is not on the heap (nor is a static) is not enough. The
object might be a member of a larger dynamically allocated object.
In general, as DeadMG said, there's no way you can tell from a pointer where it comes from. However, as a debugging or porting or analyzing measure, you could add a member operator new to your class which tracks dynamic allocations (provided nobody uses the explicit global ::new -- that includes containers, I'm afraid). You could then build up a set<T*> of dynamically allocated memory and search in there.
That's not at all suitable for any sort of serious application, but perhaps this can help you track where things are coming from. You can even add debug messages with line numbers to your operator.
No, it's impossible to know. You should fix the bug. In the least case, you can use a smart pointer (like shared_ptr) and give it an empty custom destructor if you don't want it to be deleted.
If you have access to the dynamic memory allocator code itself, you could scan the internal structure and see if the current pointer is in its allocated list/stack/area or however it is being stored. Quite often they are stored as linked list style structs and it wouldn't be too hard to scan for your var's address.
In my opinion it should be possible
because you can check if the memory is on the heap or on the stack
This is going to be highly platform depended code
First you have to get the range of the heap, and then you have to check if the passed memory adress is in this range...
(sounds simple, but the first step is probably tricky :-) )