Releasing a CSharedPtr in Marmalade - c++

I'm looking at Marmalade's implementation of CSharedPtr, which purports to perform reference counting. The documentation states that:
When the last CSharedPtr<> referring to a particular object goes out of scope, the reference count reaches zero, and the the delete operator is called on the object.
Is there any way to release the object without it going out of scope? I don't seem to be able to set it to NULL.

Try constructing a new CSharedPtr using the constructor that lets you pass in a pointer and then assigning that to the one you want to set to null.
CSharedPtr<T> cNullPtr( NULL );
existingPtr = cNullPtr;

Related

When do I need to initialize a pointer to nullptr?

When I am reading some example code of Qt, I usually see they initialize a pointer to nullptr, for example:
QPushButton *startButton = nullptr;
I have some very basic idea of nullptr, but never really used it once since I have started to learn C++. So I wonder why they will initialize a pointer to nullptr instead of just doing like this: QPushButton *startButton;, What is the benefit of doing that and when do I need to initialize a pointer to nullptr?
Thanks in advance.
You need to initialize a pointer before you read it.
If you only sometimes initialize it to a sensible value before it is read, then initializing it to nullptr at the point of declaration makes sense since then you'll be able to detect nullptr as "not yet initialized to something reasonable".
Leaving the pointer uninitialized is no good if there's a path in your program that may then read it before it is initialized, since reading an uninitialized variable is Undefined Behaviour.
When do I need to initialize a pointer to nullptr?
In situations where you cannot initialize a pointer to an address of an object (possibly because that object does not yet exist, or perhaps only ever exists conditionally), but you need to be able to check whether the pointer does point to an object or not.
You can know that a pointer that points to null definitely does not point to an existing object. If you define the post-conditions and invariants of your program correctly, you'll be able to prove that a pointer always points to either null, or a valid object.
Null isn't the only option. Another option is to initialize to a static object that always exists. This is typical solution in node based (i.e. link based) data structures where that static object is called a sentinel node.

found/not-found indication with shared_ptr

I routinely use following primitive elements in some internal tables.
X const* find(Key const& key);
If found return pointer to found element if not found return null.
I would like to do something similar with shared_ptr instead of naked pointer.
No problem, it works the same way more or less. shared_ptr has a default constructor which makes a "null" pointer, and it also has an operator which lets you evaluate the shared_ptr in a boolean context like an if conndition. So when you have nothing to return, just say:
return shared_ptr<X>();
And to test it:
if (shared_ptr<X> ptr = myFunc()) {
// do something with *ptr
}
I don't know why you're insisting on returning shared_ptr? shared_ptr are tools for managing memory. You can use these inside your function. However it won't make any difference to caller of your function whether you are returning a shared_ptr, reference/raw-pointer.( In an asynchronous context, there are many pitfalls ).
Also, shared_ptr's are based on reference counting mechanism i.e they are deleted only when it is no longer referenced by anyone. So, if you are returning it you have to make sure you are not storing it permanently which would never enable it's reference count to reach 0.

Updating a static member in a function call causes crash

I have a class polymer with a static int count.
When I create a new polymer to add to an array of pointers I am using the count to find the correct location in the array and then I update the count in the constructor. While compiling in Windows it worked. However, when compiling in Linux (Ubuntu) it crashes unless I remove the updating of the count out of the constructor.
WORKS in Windows and Ubuntu:
polymerPointer[polymer::count] = new polymer();
polymer::count++;
WHEN the constructor doesn't update the static variable (see below)
polymer::polymer(){
//sets up lots of variables but doesn't update the static member
};
CRASHES in Ubuntu (works in Windows):
polymerPointer[polymer::count] = new polymer();
WHEN the constructor does update the static variable (see below)
polymer::polymer(){
//sets up lots of variables and then updates the static member
count++;
};
I can rewrite the code, but I liked not having to remember to update the variable separately, which is why I put the update in the constructor. Any ideas on what is going wrong?
You're hitting undefined behavior.
The following:
polymerPointer[polymer::count] = new polymer();
polymer::count++;
is not equivalent to
polymerPointer[polymer::count] = new polymer();
where polymer() increments polymer::count.
The undefined behavior results from the fact that you're modifying a value and using that value in the same statement:
§1.9 p15 If a side effect on a scalar object is unsequenced relative
to either another side effect on the same scalar object or a value
computation using the value of the same scalar object, the behavior is
undefined.
What probably is occuring is that the count is incremented and then the object is placed in that new position in the array. Now code will access the empty spot left as though it held a valid pointer, or when you get to the end of an array you may try to place the pointer out of the bounds of the array.
It's bad design to put the count increment in a different place than where you actually insert into the array. What you should do is write a static member function that adds elements to the array and updates the count, and then use that instead of manually creating the object and manually placing it in the array, while expecting the count to get updated automatically.
class polymer {
static void create_new_polymer() {
polymerPointer[polymer::count] = new polymer();
count++;
}
};
Even better would be to just use a vector and have it manage it's own count:
polymerPointer.push_back(new polymer());
The compiler may legally evaluate polymerPointer[polymer::count] before new polymer(); or the other way around, as it wishes. This means that you cannot depend on polymer::count to be the original value. You must use something more deterministic, like std::vector<std::unique_ptr<Polymer>>?
It could be due to an uninitialised variable. Try stepping through the code in a debugger or just printing out the value of count.
You could also check that polymerPointer points to allocated memory (how much memory did you allocate for the storage and is it enough for all values of count?).
Your problem is that the standard doesn't guarantee in which order your statement is executed, so polymerPointer[polymer::count] = new polymer(); might evaluate polymer::count either before or after new polymer(); is executed.
If you change polymer::count inside of polymers constructor and polymer::count is evaluated after new polymer() you obviously skip indices, which is likely what leads to your crashes.
But do you really have any pressing reason to use what seems like a c-style array here instead of using std::vector (which would not need the extra count variable)? Furthermore if you have the choice you really shouldn't use manual memory management, so use std::unique_ptr or std::shared_ptr if you have access to C++11, std::tr1::shared_ptr or boost::shared_ptr otherwise. If you are using boost boost::ptr_vector is also an option
The easiest fix would be to split that assignment in two, hence introducing a sequencing:
polymer*& insert_point = polymerPointer[polymer::count];
insert_point = new polymer();
The reasoning is explained in other answers.

C++ Pointer (Pass By Reference) Question

A pointer that is passed-in-by-reference. Why? aren't pointers just references anyways? What's really happening to this parameter?
void someFunc(MyPtr*& Object)
{
}
Simply speaking, it gives you the ability to change the pointer itself: it can be changed to point to another location in the function.
And the change will be reflected outside.
It enable you to:
void someFunc(MyPtr*& Object)
{
//Modify what Object is pointing to
Object=&old_Object;
//You can also allocate memory, depending on your requirements
Object=new MyPtr;
//Modify the variable Object points to
*Object=another_object;
}
Other's will have to vote to verify this cause I'm a bit rusty on my C++ but I believe the idea here is you'd pass in a pointer by reference, that is instead of creating a new space to store the pointer itself you use a reference to the pointer so if you were to modify the pointer not just the value it would be modified after returning from the function, whereas otherwise all you could do is modify the value at position passed in. Hope that makes sense.
The difference to passing just a pointer is that if the pointer is changed (Object = x) then this change will be seen by the calling function. You could achieve the same when you pass MyPtr** Object and dereference the pointer *Object = x;. With the second approach you could pass NULL to the function. This is not possible for references.
You are not quite right. The pointer content is passed by reference but the pointer itself is still passed by value, i.e. reassinging it to some other pointer will not be reflected upon the exit from the method because the pointer will be set to point to the same memory block as before the call. Think of it as a simple int variable. However with &* or ** you can reassign the pointer and that will be visible outside the scope of this method.
Why?
For the same reason that you would pass in anything else by reference.
aren't pointers just references anyways?
Dear god, no. Not even remotely the same thing. Look, you can try to build a mental model of a reference by starting with a pointer, but by the time you've fixed up all the differences, you have a horrible illogical mess.
References are a much simpler and more intuitive concept, and there are only "historical reasons" for trying to understand pointers before them. Modern C++ uses raw pointers only rarely, and treats them as an implementation detail as much as possible.
A reference is another name for an already-existing thing. That's it. When used as a function parameter, they thus allow the called function to refer to the caller's data.
It also means the pointer can be 0 (NULL) which can having meaning to the method. A reference must always be valid and cannot be made 'nothing'

Create an instance from a static method

let's say I want my users to use only one class, say SpecialData.
Now, this data class would have many methods, and depending on the type of data, the methods do different things, internally, but return externally similar results. Therefore my wanting to have one "public" class and other "private", child classes that would change the behavior of methods, etc...
It would be amazingly more simple for some types of data that need to be built to do something like this:
SpecialData& sm = SpecialData::new_supermatrix();
and new_supermatrix() would return a SuperMatrix instance, which inherits from most behaviors of SpecialData.
my header:
static SpecialData& new_supermatrix();
my cpp:
SpecialData& SpecialData::new_supermatrix()(){
return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...);
}
The problem is, I get this error, which is probably logical due to the circumstances:
invalid initialization of non-const reference of type ‘SpecialData&’ from a temporary of type ‘SpecialData’
So, any ideas?
Well, you've got three choices:
a) You want to have only one instance of SuperMatrix anyway. Then go for the static function member route as has already been suggested.
b) You want to create multiple instances. Then you have to return a pointer instead of references and create the objects with with new (i.e. return new SuperMatrix(...).
c) As an alternative to option b, you can also return merely an object, i.e.
SpecialData SpecialData::new_supermatrix()(){
return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...);
}
However, this requires a (deep-)copy operator (the default one won't suffice more often than not), and it means that the object is created on the stack, then copied and that copy is being returned. The good thing is, this won't leak memory if you don't actually receive the result into a variable. The bad thing is, if the object is very large, this can be very memory- and time-consuming.
Whatever you are going to do with it, these solutions are mutually exclusive, both technically and logically. ;)
Simple answer - you can't use references like that. Your new_supermatrix function returns a nameless temporary value which you try to bind to a non-const reference - C++ only allows such values to be bound to const references. If you want to write functions like this, you need to make them return a pointer to a dynamically allocated object, or stick with returning a value, but assign the return value to another value in the calling code.
This code has several problems. First of all, you probably want to use pointers here instead of references. Returning a reference to an object created on the stack like you do in your new_supermatrix will lead to a crash almost immediately. It needs to be allocated with new and passed back as a pointer if that's what you want but I'm not exactly sure what you're trying to do. But anyway, this is what's causing your error, you're returning a reference to a temporary variable.
You need to actually use the new operator. The creation you get by return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...); allocates the object on the stack, which is cleaned up when the function returns (which it is doing in the same line). Using new causes it to be allocated on the heap.
In your method, you can use a static:
SpecialData& SpecialData::new_supermatrix()(){
static SuperMatrix supermatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...);
return supermatrix;
}
You must not return a reference to a temporary/local object.
This and many other common errors-to-be-avoided are explained in Meyers' book, Effective C++.
You're returning a reference to a temporary object, which is bad news, since once your method exits, the object doesn't exist anymore.
Read up on creational design patterns. The one that looks closest to what you want to do is the Factory Method pattern.