I'm using the gsl library in C++. I have declared a gsl_vector pointer mesh as a private member of the class.
private:
gsl_vector * mesh;
I also have a method, MeshBuilder, that declares a gsl_vector, pointer mesh (over-riding the original mesh variable) and returns mesh.
gsl_vector * ThinFilm::LinearMesh(...){
gsl_vector * mesh = gsl_vector_alloc(numberofcells);
...
return mesh;
}
I then assign the result of the method to the variable mesh as:
mesh = MeshBuilder(...);
It compiles and runs just fine (no warnings either, with -Wall). Stepping through the program I noticed that the variable mesh is assigned an address, and then the MeshBuilder overwrites that. Which is exactly what I programmed to do.
But is it good practice? After all, shouldn't I not assign a value to the pointer address?
Shouldn't I instead not declare a the mesh pointer in the MeshBuilder method and therefore directly use the pointer declared in the private section of the class?
I'm guessing the only reason this works is because the address value I'm assigning to mesh is in fact valid having been declared.
The mesh variable in the method shadows the private's variable.
If you use the private variable directly, then you avoid declaring a temporary, but in practice, it does not change much.
However, if the interface of the class is to be used in multithreaded contexts, then changing the private variable directly will make it visible to any other thread at the allocation time, so if the ... section in the code above does some sort of setup of the vector, it means other thread might see or use an invalid (not constructed) variable.
In that case, you should use a temporary (like in your initial code) and protect the assignment mesh = MeshBuilder(...) with either a mutex or an atomic operation (like CAS, or pointer exchange).
Also, in all cases, if you want to write safe code, you should also consider what is going to happen is an exception is thrown in the ... part of the code.
Setting the private variable directly, you might have a chance to clean the allocation (in the destructor of your class), else you'll get a memory leak since a pointer does not clean the allocation by itself.
If you want a really safe code that's working in all possible conditions, you should use a smart pointer in place of the temporary (for exception safe code), a mutex to protect private variable access (for multithread safe code).
Simple answer is no, in your current code, you are leaking a resource.
The problem is gsl_vector_alloc does not return a value, but indeed an address, which point to a struct that contain the value you except to see. In this context, gsl_vector_alloc is behaving similar to using new, as it allocating a vector struct, and initializing it.
The function gsl_vector_alloc, as it name suggest allocate a vector. This mean you need to free it with gsl_vector_free before you are overriding it.
Also allocation can fail, in such a case gsl_vector_alloc will return NULL and you will have to check for it, before using mesh.
Side note: In the function you are providing you call your local variable mesh, which has the same name as a private member, this is a bad practice as the local variable will hide the private member.
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.
class MyClass {
private:
unsigned int currentTimeMS;
public:
void update() {
currentTimeMS = getTimeMS();
// ...
}
};
class MyClass {
public:
void update() {
unsigned int currentTimeMS = getTimeMS();
// ...
}
};
update() calls in main game loop so in the second case we get a lot of allocation operations (unsigned int currentTimeMS). In the first case we get only one allocate and use that allocated variable before.
Which of this code better to use and why?
I recommend the second variant because it is stateless and the scope of the variable is smaller. Use the first one only if you really experience a performance issue, which I consider unlikely.
If you do not modify the variable value later, you should also consider to make it const in order to express this intent in your code and to give the compiler additional optimization options.
It depends upon your needs. If currentTimeMS is needed only temporarily in the update(), then surely declare it there. (in your case, #option2)
But if it's value is needed for the instance of the class (i.e. being used in some other method), then you should declare it as a field (in your case, #option1).
In the first example, you are saving the state of this class object. In the second one, you're not, so the currentTime will be lost the instant update() is called.
It is really up to you to decide which one you need.
The first case is defining a member variable the second a local variable. Basic class stuff. A private member variable is available to any function (method) in that class. a local variable is only available in the function in which it is declared.
Which of this code better to use and why?
First and foremost, the cited code is at best a tiny micro-optimization. Don't worry about such things unless you have to.
In fact, this is most likely a disoptimization. Sometimes automatic variables are allocated on the stack. Stack allocation is extremely fast (and even free sometimes). There is no need to worry. Other times, the compiler may place a small automatic variable such the unsigned int used here in a register. There's no allocation whatsoever.
Compare that to making the variable a data member of the class, and solely for the purpose of avoiding that allocation. Accessing that variable involves going through the this pointer. Pointer dereference has a cost, potentially well beyond that of adding an offset to a pointer. The dereference might result in a cache miss. Even worse, this dereferencing may well be performed every time the variable is referenced.
That said, sometimes it is better to create data members solely for the purpose of avoiding automatic variables in various member functions. Large arrays declared as local automatic variables might well result in stack overflow. Note, however, that making double big_array[2000][2000] a data member of MyClass will most likely make it impossible to have a variable of type MyClass be declared as a local automatic variable in some function.
The standard solution to the problems created by placing large arrays on the stack is to instead allocate them on the heap. This leads to another place where creating a data member to avoid a local variable can be beneficial. While stack allocation is extremely fast, heap allocation (e.g., new) is quite slow. A member function that is called repeatedly may benefit by making the automatic variable std::unique_ptr<double> big_array = std::make_unique<double>(2000*2000) a data member of MyClass.
Note that neither of the above applies to the sample code in the question. Note also that the last concern (making an heap-allocated variable a data member so as to avoid repeated allocations and deallocations) means that the code has to go through the this pointer to access that memory. In tight code, I've sometimes been forced to create a local automatic pointer variable such as double* local_pointer = this->some_pointer_member to avoid repeated traversals through this.
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 passing HBuf to function
but it crashes i don't know whether i am following right way or not
//case 1:
HBufC8* iBuffer2 = HBufC8::NewL(1000 );
TPtr8 bufferPtr( iBuffer2->Des() );
//assigning value to HBuf code
StartParsingL(iBuffer2);
StartParsingL(HBufC8* aHBufPtr)
{
iBuffer = HBufC8::NewL(aHBufPtr->Length());//it crashes here
bufferPtr.Copy(aHBufPtr->Des());//also here
}
Not answering your question (as there isn't really enough information). I would recommend using an RBuf instead of a HBuf as they are the recommended heap buffer descriptor going forward, and a bit easier to use.
In the Symbian coding convention, "i" prefixed variables are member variables.
In your snippet you have it as a local declaration. It could be that you just put in the type for clarity of the snippet, but if you've declared it both as a member variable and as a local declaration, that could explain plenty of crashes :-)
You should have:
class C....: public CBase?....
{
private:
HBufC8* iBuffer2;
};
...
void C...::ConstructL()
{
...
iBuffer2 = HBufC8::NewL(1000);
...
}
This code does not directly show the reason for crashing. Please post actual snippets next time.
Also, when posting about a crash, it is good to know how it is crashing. I assume it is a KERN-EXEC 3 panic. But please be explicit about it yourself.
I guess the aHBufPtr passed to StartParsingL is either zero or otherwise does not point to a valid HBuf8 object. That would be the immediate reason for the crash. Why it is not a valid pointer is not visible in the code, but one reason could be shadowing a member variable with a local variable as suspected by #Will.
Some further points, not related to crash here but Symbian C++ in general:
When passing descriptors around, you should use the most general read-only TDesC or TDesC8 type references or read-write TDes or TDes8 type references. Use HBufC or HBufC8 pointers only if you are transferring ownership to the callee.
In this snippet:
bufferPtr.Copy(aHBufPtr->Des());
Copy accepts a TDesC& so you do not need to call Des:
bufferPtr.Copy(*aHBufPtr);
Though if you just want to copy a descriptor, you could use any of the descriptor Alloc functions such as AllocL.
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.