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.
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.
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'm a c++ newbie, my code currently new's up on the heap in several places without calling delete. I know I need to do something about this.
My typical usage is where I new up a class instance in another classes member method then the method returns the pointer to the object.
If i change the return types from MyType* to std::tr1::shared_ptr will this fix my code to not leak memory?
Thanks a lot.
Edit:
Also likewise, I currently store new'ed up objects as MyType* as a value in a std:map. This map is a private member to a class instance. If I simply change this to std::tr1::shared_ptr will this clear up these when it's owner (class) falls out of scope?
Thanks again
It's a reasonable band-aid, sure.
A shared pointer is a reference-counted pointer. So as long as one or more shared_ptrs exist pointing to an object, that object will be kept alive. The problem occurs if you have circular references. Then the reference count will never reach 0, and the object(s) will never be deleted.
So shared_ptr * still* require you to understand what you're doing and think about object ownership, as you always have to do in C++. But it simplifies some otherwise complex scenarios, where determining ownership is hard.
But the real fix to your problem is to:
minimize how much you allocate with new. Can the object instead be stored on the stack? Can the object be rewritten as a RAII class, so that a small wrapper object is allocated on the stack (or elsewhere with automatic storage duration), and which, through its constructors and destructors, manages a heap-allocated memory resource? Then, as long as that object exists, its allocated memory will be preserved, and once it is destroyed, it will delete its allocated memory.
when you allocate objects with new, put them in one of the smart pointer classes. shared_ptr is popular because it is the one that comes closest to looking like a garbage collector, but it isn't, and if you treat it as one and use it as an excuse to not think about memory management, then it won't work. Understand all the smart pointer classes (scoped_ptr and auto_ptr in C++03, or unique_ptr replacing both in C++11, shared_ptr and weak_ptr), and use the one that best fits your scenario.
think about ownership. Any time you allocate memory, you need to determine an owner, whose lifetime will control the lifetime of the memory allocation. Think about how long a lifetime your allocation needs, and have another object (whose lifetime is automatically managed, probably because it is on the stack) delete your memory when its destructor is called.
There's no quick and easy fix. The way to handle memory management in C++ is to avoid memory management. Delegate it out to your objects. If you're calling delete in your own code, you're doing it wrong. Often, you don't even need new, but if you do, assign ownership to a smart pointer immediately, and let that call delete for you.
As a rule of thumb, unless you're a library writer, you shouldn't write either new or delete. You should virtually never use raw pointers, and only when it is absolutely necessary, use smart pointers. Let your classes do the heavy lifting. Don't be afraid to put them on the stack, pass them by value, and let them handle their resources internally.
If you are new to C++ there are a few points with pointer management you need to understand and accept, regardless of whether you're using shared_ptr or not.
It is more than likely in your use of C++ you will need to use new and assign its return pointer to a class pointer that you have declared. I believe it is advisable to take the time to understand what is going on there, even if you write a small test program and watch the constructor execute in the debugger.
If you use classes like std::string, its constructors and destructor will do string pointer management for you, but I believe it is a good idea to understand what is going on behind the scenes in that class, if nothing more than reading the documentation.
As another example, you cannot use some classes, without a lot of detailed reading of the API, or you'll get problems. I once worked at company that used a commercial class package years ago. Someone had written a multi-threaded program using this package's thread pool class.
The documentation clearly said you can't just exit with outstanding threads. Yet I saw where the author of the program did not bother to synch up and shutdown all threads on exit, and wound up throwing exceptions, when their program exited. And this was on a commercial financial product.
My suggestion is don't look to get saved from performing pointer management. There are std classes like string that can reduce your headaches, but nothing will prevent problems other than your own diligence and testing.
As long as you understand how tr1 shared pointers work, yes.
Look at Boost C++ shared_ptr<> also - it might be more what you want.
I have a notion that C++ runtime doesn't do any heap compaction which means that the address of an object created on heap never changes. I want to confirm if this is true and also if it is true for every platform (Win32, Mac, ...)?
The C++ standard says nothing about a heap, nor about compaction. However, it does require that if you take the address of an object, that address stays the same throughout the object's lifetime.
A C++ implementation could do some kind of heap compaction and move objects around behind the scenes. But then the "addresses" it return to you when you use the address-of operator, are not actually memory addresses but some other kind of mapping.
In other words, yes, it is safe to assume that addresses in C++ stay the same while the object you're taking the address of lives.
What happens behind the scenes is unknown. It is possible that the physical memory addresses change (although common C++ compilers wouldn't do this, it might be relevant for compilers targeting various forms of bytecode, such as Flash), but the addresses that your program sees are going to behave nicely.
The standard does not specify it, but then the standard does not specify a heap. This is entirely dependent on your implementation. However, there is nothing stopping an implementation compacting unused memory while maintaining the same addreses for objects in use.
You are right it does not change. Pages can be moved around in physical memory but the Translation Lookaside Buffer (This is what control virtual memory) hides all that from you.
I'm unaware of any C++ implementation that will move allocated objects around. I suppose it might be technically permitted by the standard (though I'm not 100% sure about that), but remember that the standard must allow a pointer to be cast to a large enough integral type and back again and still be a valid pointer. So an implementation that could move dynamically allocated objects around would have to be able to deal with the admittedly unlikely series of events where:
a pointer is cast to an intptr_t
that value is transformed somehow (xor'ed with some value), so the runtime can't detect that it's a pointer to a particular object
the object gets moved due to compaction
the intptr_t gets transformed back into its original value, and
cast back to a pointer to the object type
The implementation would need to ensure that the pointer from that last step points to the moved object's new location.
I suppose using double indirection for pointers might allow an implementation to deal with this, but I'm unaware of any implementation that does anything like this.
Under normal circumstances when you're using the system compiler's default runtimes, you can safely assume that pointers will not be invalidated by the runtime.
If you are not using the default memory managers, but a 3rd-party memory manager instead, it completely depends on the runtime and memory manager you are using. While C++ objects do not generally get moved around in memory by the memory manager, you can write a memory manager that compacts free space and you could conceivably write one that would move allocated objects around to maximise free space as well.
What is the best practice when returning a smart pointer, for example a boost::shared_ptr? Should I by standard return the smart pointer, or the underlying raw pointer? I come from C# so I tend to always return smart pointers, because it feels right. Like this (skipping const-correctness for shorter code):
class X
{
public:
boost::shared_ptr<Y> getInternal() {return m_internal;}
private:
boost::shared_ptr<Y> m_internal;
}
However I've seen some experienced coders returning the raw pointer, and putting the raw pointers in vectors. What is the right way to do it?
There is no "right" way. It really depends on the context.
You can internally handle memory with a smart pointer and externally give references or raw pointers. After all, the user of your interface doesn't need to know how you manage memory internally. In a synchronous context this is safe and efficient. In an asynchronous context, there are many pitfalls.
If you're unsure about what to do you can safely return smart pointers to your caller. The object will be deallocated when the references count reaches zero. Just make sure that you don't have a class that keeps smart pointers of objects for ever thus preventing the deallocation when needed.
As a last note, in C++ don't overuse dynamically allocated objects. There are many cases where you don't need a pointer and can work on references and const references. That's safer and reduces the pressure on the memory allocator.
It depends on what the meaning of the pointer is.
When returning a shared_pointer, you are syntactically saying "You will share ownership of this object", such that, if the the original container object dies before you release your pointer, that object will still exist.
Returning a raw pointer says: "You know about this object, but don't own it". It's a way of passing control, but not keeping the lifetime tied to the original owner.
(in some older c-programs, it means "It's now your problem to delete me", but I'd heavily recommend avoiding this one)
Typically, defaulting to shared saves me a lot of hassle, but it depends on your design.
I follow the following guidelines for passing pointers arguments to functions and returning pointers:
boost::shared_ptr
API and client are sharing ownership of this object. However you have to be careful to avoid circular references with shared_ptr, if the objects represent some kind of graph. I try to limit my use of shared_ptr for this reason.
boost::weak_ptr / raw pointer
API owns this object, you are allowed share it while it is valid. If there is a chance the client will live longer than the api I use a weak_ptr.
std::auto_ptr
API is creating an object but the client owns the object. This ensures that the returning code is exception safe, and clearly states that ownership is being transferred.
boost::scoped_ptr
For pointers to objects stored on the stack or as class member variables. I try to use scoped_ptr first.
Like all guidelines there will be times when the rules conflict or have to be bent, then I try to use intelligence.
I typically return "owning"/"unique" smart pointers from factories or similar to make it clear who is responsible for cleaning up.
This example https://ideone.com/qJnzva shows how to return a std::unique_ptr that will be deleted when the scope of the variable that the caller assigns the value to goes out of scope.
While it's true that the smart pointer deletes its own pointer, the lifetime of the variable holding the smart pointer is 100% controlled by the caller, so the caller decides when the pointer is deleted. However, since it's a "unique" and "owning" smart pointer, no other client can control the lifetime.
I would never return a raw pointer, instead I would return a weak_ptr to tell the user of the pointer that he doesn't have the control over the resource.
If you return a weak_ptr its very unlikely that there will be dangling pointers in the application.
If there is a performance problem I would return a reference to the object and a hasValidXObject method.
In my opinion, in C++, you should always have to justify the use of an unguarded pointer.
There could be many valid reasons: a need for very high performance, for very low memory usage, for dealing with legacy libraries, because of some issue with the underlying data structure the pointer is storing. But [dynamically allocated] pointers are somewhat 'evil', in that you have to deallocate the memory at every possible execution path and you will almost certainly forget one.
I wouldn't put raw pointers in vectors.
In case they use auto_ptr or boost::scoped_ptr, they can't use (or return) anything but raw pointers. That could explain their way of coding, i guess.
depends on your goals.
blindly returning smart ptr to internal data might not be a good idea (which is very sensitive to the task you're trying to solve) - you might be better off just offering some doX() and doY() that use the pointer internally instead.
on the other hand, if returning the smart ptr, you should also consider that you'll create no mutual circular references when objects end up unable to destroy each other (weak_ptr might be a better option in that case).
otherwise, like already mentioned above, performance/legacy code/lifetime considerations should all be taken into account.
const boost::shared_ptr &getInternal() {return m_internal;}
This avoids a copy.
Sometimes you'll like to return a reference, for example:
Y &operator*() { return *m_internal; }
const Y &operator*() const { return *m_internal; }
This is good too only if the reference will be used and discarded inmediately.
The same goes for a raw pointer.
Returning a weak_ptr is also an option.
The 4 are good depending on the goals. This question requires a more extensive discussion.