I have a situation in which I have an object of type Foo, in which calling its own methods somehow loses track of its own address in "this". I have defined these functions:
// Bar has an instance of foo, and wishes to call a function001()...
Bar::doThingWithFoo(){
// foo is at address 0x1a7bbb70 here...
foo->function001();
}
// The definition of function001(). The address of "this" is as expected.
Foo::function001(){
// the address of "this" is 0x1a7bbb70 here...
this->function002();
}
Foo::function002(){
// but the address of "this" is 0xbfffe090 here!!!
// bad things happen, as you might expect.
this->getMyProperty()->doThing();
}
Why might something like this happen?
Perhaps you are using multiple inheritance, which causes the pointer value of this to be context-dependent:
http://frogchunk.com/documentation/lang/cpp/Multiple_inheritance_and_the_this_pointer.pdf
That causes problems if you use C casts instead of dynamic_cast.
I agree with the comments that we need to see the actual code. I will speculate that 0xbfffe090 looks like an address on the stack which means you may have accidentally copied your object and then invoked a method on the copy. It would also be consistent with some kind of memory corruption (overwriting a local array, for example) with some local address.
Wild speculative guess would be what others have also eluded to that you might be having some sort of buffer over-flow case at other place in your code where the buffer overflow is corrupting this.
It would help to know the code.
I would imagine if its a memory corruption it would cause it have a core dump, did you notice one ?
Answering my own question : alltom's answer was actually closer than it might seem, but ultimately it was of course memory corruption. Memory became corrupted inside function001 prior to function002 being called because of an object being used as a delegate. The delegate had been passed and stored as a void*, and C-style cast back into its object type to call its relevant methods.
The issue was resolved by storing the delegate object in a variable (eg: MyDelegate* delegate) rather than storing as void* and casting.
Related
Is there a well-defined way of accessing the vtable of a class? When debugging in visual studio I can expand 'this' like: this->_ptr->__vfptr. But this path does not seem to be available from code.
I need this for a unit test of a custom heap implementation (embedded environment).
Background
We had a bug where an object being allocated on our custom heap (which isn't anything more than an array of a certain size) was working as expected until we wanted to add an object having a virtual function (it took quite some time before we realized that this addition was the cause of the problem). The mistake that we did was to assign an object to memory where no object had been initialized prior to assignment. We did not pay much attention when writing that code and as it worked with everything else and was tested, we considered it working. Here's some sample code:
int array_ptr[sizeof(SomeObject)];
*((SomeObject*) array_ptr) = SomeObject(); // Does only partially initialize the object!
Once we realized this line was the issue, it also became clear why that was the case.
Aha, I get it now, with the clarification from the comments.
You're calling CFoo::operator= on raw memory that only has the size of a CFoo. That's indeed not going to set a vtable, on common implementations. This is specific to how assignment in C++ works. Object assignment in C++ is defined to be slicing. If you assign a Derived object to a Base class, you're calling Base::operator=(Base const& src). This only copies the Base sub-object of the Derived object.
The reason why C++ chose this model is because that means the Base object doesn't change size when you assign a Derived value to it, at the obvious price of losing the extra information.
The net effect is that C++ objects do not change type after construction. Practically, that means the type, and the vtable can be fixed by the constructor. The assignment operator won't touch it.
So, by calling the assignment operator on raw memory, you get Undefined Behavior, in particular an uninitialized (garbage) vtable. You can't count on it being all zeroes. Also, in more complicated cases with multiple and virtual inheritance, there are additional data fields to find the various sub-objects. Those would be uninitialized as well. Note that these additional data fields may contain absolute pointers. memcpy such an object, and you'd point back to subobjects of the original.
Can you detect this? No. All your attempts to access the memory are Undefined Behavior, by virtue of there not being a CFoo object in the raw memory.
The solution is placement new. This is the magical incantation that turns raw memory into an object. It can use any constructor, including move constructors and copy constructors, but (barring exceptions) will leave you with a valid object, with proper polymorphic behavior.
Ok, so learning from MSalters and other commenters above I understand there is no straight forward way of reading the vtable pointer. However, I came up with a solution that was enough for my needs (i.e. to test that the vtable pointer is properly initialized). So here's the code (note that I assume that what I get is the vtable pointer as sizeof(size_t) == sizeof(EmptyClassWithOneVirtualFunction)):
class EmptyClassWithOneVirtualFunction
{
virtual void testFunction() {}
};
void test_staticNew_object_vtable()
{
EmptyClassWithOneVirtualFunction correctObject;
EmptyClassWithOneVirtualFunction* object = mem::static_new<EmptyClassWithOneVirtualFunction>();
size_t* correctObjectVtablePtr = ( (size_t*) &correctObject );
size_t* objectVtablePtr = ( (size_t*) object );
TS_ASSERT_EQUALS( *objectVtablePtr, *correctObjectVtablePtr );
}
It should be pointed out that this is test code that is built in debug mode without optimization. To be able to catch this error even in this not entirely "safe" way is more valuable to me than to skip doing it just because there is no right way to do it.
I recently came across some C++ code that looked like this:
class SomeObject
{
private:
// NOT a pointer
BigObject foobar;
public:
BigObject * getFoobar() const
{
return &foobar;
}
};
I asked the programmer why he didn't just make foobar a pointer, and he said that this way he didn't have to worry about allocating/deallocating memory. I asked if he considered using some smart pointer, he said this worked just as well.
Is this bad practice? It seems very hackish.
That's perfectly reasonable, and not "hackish" in any way; although it might be considered better to return a reference to indicate that the object definitely exists. A pointer might be null, and might lead some to think that they should delete it after use.
The object has to exist somewhere, and existing as a member of an object is usually as good as existing anywhere else. Adding an extra level of indirection by dynamically allocating it separately from the object that owns it makes the code less efficient, and adds the burden of making sure it's correctly deallocated.
Of course, the member function can't be const if it returns a non-const reference or pointer to a member. That's another advantage of making it a member: a const qualifier on SomeObject applies to its members too, but doesn't apply to any objects it merely has a pointer to.
The only danger is that the object might be destroyed while someone still has a pointer or reference to it; but that danger is still present however you manage it. Smart pointers can help here, if the object lifetimes are too complex to manage otherwise.
You are returning a pointer to a member variable not a reference. This is bad design.
Your class manages the lifetime of foobar object and by returning a pointer to its members you enable the consumers of your class to keep using the pointer beyond the lifetime of SomeObject object. And also it enables the users to change the state of SomeObject object as they wish.
Instead you should refactor your class to include the operations that would be done on the foobar in SomeObject class as methods.
ps. Consider naming your classes properly. When you define it is a class. When you instantiate, then you have an object of that class.
It's generally considered less than ideal to return pointers to internal data at all; it prevents the class from managing access to its own data. But if you want to do that anyway I see no great problem here; it simplifies the management of memory.
Is this bad practice? It seems very hackish.
It is. If the class goes out of scope before the pointer does, the member variable will no longer exist, yet a pointer to it still exists. Any attempt to dereference that pointer post class destruction will result in undefined behaviour - this could result in a crash, or it could result in hard to find bugs where arbitrary memory is read and treated as a BigObject.
if he considered using some smart pointer
Using smart pointers, specifically std::shared_ptr<T> or the boost version, would technically work here and avoid the potential crash (if you allocate via the shared pointer constructor) - however, it also confuses who owns that pointer - the class, or the caller? Furthermore, I'm not sure you can just add a pointer to an object to a smart pointer.
Both of these two points deal with the technical issue of getting a pointer out of a class, but the real question should be "why?" as in "why are you returning a pointer from a class?" There are cases where this is the only way, but more often than not you don't need to return a pointer. For example, suppose that variable needs to be passed to a C API which takes a pointer to that type. In this case, you would probably be better encapsulating that C call in the class.
As long as the caller knows that the pointer returned from getFoobar() becomes invalid when the SomeObject object destructs, it's fine. Such provisos and caveats are common in older C++ programs and frameworks.
Even current libraries have to do this for historical reasons. e.g. std::string::c_str, which returns a pointer to an internal buffer in the string, which becomes unusable when the string destructs.
Of course, that is difficult to ensure in a large or complex program. In modern C++ the preferred approach is to give everything simple "value semantics" as far as possible, so that every object's life time is controlled by the code that uses it in a trivial way. So there are no naked pointers, no explicit new or delete calls scattered around your code, etc., and so no need to require programmers to manually ensure they are following the rules.
(And then you can resort to smart pointers in cases where you are totally unable to avoid shared responsibility for object lifetimes.)
Two unrelated issues here:
1) How would you like your instance of SomeObject to manage the instance of BigObject that it needs? If each instance of SomeObject needs its own BigObject, then a BigObject data member is totally reasonable. There are situations where you'd want to do something different, but unless that situation arises stick with the simple solution.
2) Do you want to give users of SomeObject direct access to its BigObject? By default the answer here would be "no", on the basis of good encapsulation. But if you do want to, then that doesn't change the assessment of (1). Also if you do want to, you don't necessarily need to do so via a pointer -- it could be via a reference or even a public data member.
A third possible issue might arise that does change the assessment of (1):
3) Do you want to give users of SomeObject direct access to an instance of BigObject that they continue using beyond the lifetime of the instance of SomeObject that they got it from? If so then of course a data member is no good. The proper solution might be shared_ptr, or for SomeObject::getFooBar to be a factory that returns a different BigObject each time it's called.
In summary:
Other than the fact it doesn't compile (getFooBar() needs to return const BigObject*), there is no reason so far to suppose that this code is wrong. Other issues could arise that make it wrong.
It might be better style to return const & rather than const *. Which you return has no bearing on whether foobar should be a BigObject data member.
There is certainly no "just" about making foobar a pointer or a smart pointer -- either one would necessitate extra code to create an instance of BigObject to point to.
I am having my first attempt at using C++11 unique_ptr; I am replacing a polymorphic raw pointer inside a project of mine, which is owned by one class, but passed around quite frequently.
I used to have functions like:
bool func(BaseClass* ptr, int other_arg) {
bool val;
// plain ordinary function that does something...
return val;
}
But I soon realized that I wouldn't be able to switch to:
bool func(std::unique_ptr<BaseClass> ptr, int other_arg);
Because the caller would have to handle the pointer ownership to the function, what I don't want to. So, what is the best solution to my problem?
I though of passing the pointer as reference, like this:
bool func(const std::unique_ptr<BaseClass>& ptr, int other_arg);
But I feel very uncomfortable in doing so, firstly because it seems non instinctive to pass something already typed as _ptr as reference, what would be a reference of a reference. Secondly because the function signature gets even bigger. Thirdly, because in the generated code, it would be necessary two consecutive pointer indirections to reach my variable.
If you want the function to use the pointee, pass a reference to it. There's no reason to tie the function to work only with some kind of smart pointer:
bool func(BaseClass& base, int other_arg);
And at the call site use operator*:
func(*some_unique_ptr, 42);
Alternatively, if the base argument is allowed to be null, keep the signature as is, and use the get() member function:
bool func(BaseClass* base, int other_arg);
func(some_unique_ptr.get(), 42);
The advantage of using std::unique_ptr<T> (aside from not having to remember to call delete or delete[] explicitly) is that it guarantees that a pointer is either nullptr or it points to a valid instance of the (base) object. I will come back to this after I answer your question, but the first message is DO use smart pointers to manage the lifetime of dynamically allocated objects.
Now, your problem is actually how to use this with your old code.
My suggestion is that if you don't want to transfer or share ownership, you should always pass references to the object. Declare your function like this (with or without const qualifiers, as needed):
bool func(BaseClass& ref, int other_arg) { ... }
Then the caller, which has a std::shared_ptr<BaseClass> ptr will either handle the nullptr case or it will ask bool func(...) to compute the result:
if (ptr) {
result = func(*ptr, some_int);
} else {
/* the object was, for some reason, either not created or destroyed */
}
This means that any caller has to promise that the reference is valid and that it will continue to be valid throughout the execution of the function body.
Here is the reason why I strongly believe you should not pass raw pointers or references to smart pointers.
A raw pointer is only a memory address. Can have one of (at least) 4 meanings:
The address of a block of memory where your desired object is located. (the good)
The address 0x0 which you can be certain is not dereferencable and might have the semantics of "nothing" or "no object". (the bad)
The address of a block of memory which is outside of the addressable space of your process (dereferencing it will hopefully cause your program to crash). (the ugly)
The address of a block of memory which can be dereferenced but which doesn't contain what you expect. Maybe the pointer was accidentally modified and now it points to another writable address (of a completely other variable within your process). Writing to this memory location will cause lots of fun to happen, at times, during the execution, because the OS will not complain as long as you are allowed to write there. (Zoinks!)
Correctly using smart pointers alleviates the rather scary cases 3 and 4, which are usually not detectable at compile time and which you generally only experience at runtime when your program crashes or does unexpected things.
Passing smart pointers as arguments has two disadvantages: you cannot change the const-ness of the pointed object without making a copy (which adds overhead for shared_ptr and is not possible for unique_ptr), and you are still left with the second (nullptr) meaning.
I marked the second case as (the bad) from a design perspective. This is a more subtle argument about responsibility.
Imagine what it means when a function receives a nullptr as its parameter. It first has to decide what to do with it: use a "magical" value in place of the missing object? change behavior completely and compute something else (which doesn't require the object)? panic and throw an exception? Moreover, what happens when the function takes 2, or 3 or even more arguments by raw pointer? It has to check each of them and adapt its behavior accordingly. This adds a whole new level on top of input validation for no real reason.
The caller should be the one with enough contextual information to make these decisions, or, in other words, the bad is less frightening the more you know. The function, on the other hand, should just take the caller's promise that the memory it is pointed to is safe to work with as intended. (References are still memory addresses, but conceptually represent a promise of validity.)
I agree with Martinho, but I think it is important to point out the ownership semantics of a pass-by-reference. I think the correct solution is to use a simple pass-by-reference here:
bool func(BaseClass& base, int other_arg);
The commonly accepted meaning of a pass-by-reference in C++ is like as if the caller of the function tells the function "here, you can borrow this object, use it, and modify it (if not const), but only for the duration of the function body." This is, in no way, in conflict with the ownership rules of the unique_ptr because the object is merely being borrowed for a short period of time, there is no actual ownership transfer happening (if you lend your car to someone, do you sign the title over to him?).
So, even though it might seem bad (design-wise, coding practices, etc.) to pull the reference (or even the raw pointer) out of the unique_ptr, it actually is not because it is perfectly in accordance with the ownership rules set by the unique_ptr. And then, of course, there are other nice advantages, like clean syntax, no restriction to only objects owned by a unique_ptr, and so.
Personally, I avoid pulling a reference from a pointer/smart pointer. Because what happens if the pointer is nullptr? If you change the signature to this:
bool func(BaseClass& base, int other_arg);
You might have to protect your code from null pointer dereferences:
if (the_unique_ptr)
func(*the_unique_ptr, 10);
If the class is the sole owner of the pointer, the second of Martinho's alternative seems more reasonable:
func(the_unique_ptr.get(), 10);
Alternatively, you can use std::shared_ptr. However, if there's one single entity responsible for delete, the std::shared_ptr overhead does not pay off.
I am working on tracing the constructor and its destructed instance and for that I am planning to log the value of "this" in constructor and destructor. I don't know whether it is safe to log value of "this" in constructor. If it is not safe then I wan't to know the scenarios where it will fail ?
If by "logging" you mean "writing out the value as e.g. a hexadecimal address to a log file", it is fine and safe. If not, please clarify.
Objects are not fully constructed until the constructor call is finished. So before that (i.e. from within the constructor) it is not safe to publish this to the rest of the program. Because that might result in someone trying to actually use the half-constructed object. This may lead to subtle and hard to find bugs.
Publishing this may mean one of the following things:
passing it as a parameter to an external (non-member) function,
storing it in a data structure available to other objects,
(for the sake of completeness: returning it from a function call - which does not apply in this specific case, because you can't return anything from a constructor).
Writing out the address of this to a file is thus not publishing it to the rest of your program* so it should be fine.
*well, unless you do some very arcane things afterwards, like loading back the address from the file in a different thread/process and casting it back to an object pointer... which is already unsafe enough by itself :-)
Memory is allocated first, then this is set, then the constructor(s) is called. So you're fine to use this during the constructor, as it points to the right place - the construction won't change this. However if construction fails (throws) the memory will disappear and the value pointed to by this will be garbage so you shouldn't store it and use it for anything outside the constructor until you know the construction will succeed.
Why would you think it is not safe? it is no different to logging the address of any objects in fact so long as those objects are valid.
The long and short of it is that it is safe in the scenarios you are intending to use it for.
My program is crashing every time I try to store a COM pointer into a struct, and then later try to use the original pointer. I don't have debug access to tell exactly what's wrong.
pRend->cp = cpRT;
ID2D1SolidColorBrush *scBrush;
ERF(cpRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::CornflowerBlue), &scBrush));
It crashes on CreateSolidColorBrush. However, if I comment out pRend->cp = cpRT, it doesn't.
By the way, pRend->cp and cpRT are of type ID2D1HwndRenderTarget *.
Instead of assigning directly QI and then store i.e.,
pRend->cp = cpRT;
should be replaced with
cpRT->QueryInterface(&pRend->cp);
It's unclear how much code exists between when you assign it into the struct and later use it in CreateSolidColorBrush. If it's a non-trivial amount of time, it's possible that you have a reference counting issue.
Are you storing a raw pointer in the struct? If so, switch it to a CComPtr and see if the crash goes away.
For instance. If you had the following type definition for the value of pRend (call it Render) and the value pRend was destroyed before making the CreateSolidColorBrush call, you could see this behavior.
struct Render {
ID2D1HwndRenderTarget *pCt;
~Render() {
pCt->Release();
}
};
As it turns out, I managed to stop the crashing by allocating pRend with malloc. This is not a problem because I will call free when I don't need it anymore. I'm interested in why calling malloc fixes this though. I'm used to just doing Datatype * var; and then just using var. Is that bad?
It's a smart pointer. I'm guessing you're inadvertantly calling release on it. In particular, it's addressof operator (unary op&) is overriden to call Release().
See what happens if you instead assign it to a reference, an ID2D1HwndRenderTarget*&.
Obviously, if you assign to a reference, you won't be able to reseat it.