Pages

getteammates.com

Tuesday, 30 August 2016

Finding size of an array in C/C++

It is not a good idea to hard code the size of an array. Instead we would like to somehow retrieve the size from it.

In some cases we will just initialize the array without specifying its size. In this we don't want to hard code the size as in future we might want to add more values to it.

An old way(the C way) of retrieving the size is to calculate the size of the whole array and then divide it with the size of an element in the array. This can be done as,
int i[] = {1, 2, 3};
int size = sizeof(i)/sizeof(i[0]);

// Usually please will write a macro to do this
#define ARRAY_SIZE(a) (sizeof((a))/sizeof((a[0])))


In C++ there is a way to retrieve the size of an array using templates.
template<typename T, std::size_t size>
std::size_t arrSize(T(&)[size]) {
    return size;
}

int i[] = { 1, 2, 3, 4 };
int size = arrSize(i);  // size will have 4 after this statement is executed

Another approach is to use std::array available from C++11. The only downside is that we should know the size while declaring the array
std::array<int, 4> a = { 1, 2, 3, 4 }; // Initialize as { { 1, 2, 3, 4 } } in C++11
int size = a.size(); // size will have 4 after this statement is executed

Another approach is to use std::vector(may be a little heavy if you are just looking for a fixed size array), using the universal initialize available from C++11.
std::vector<int> a = { 1, 2, 3, 4 };
int size = a.size(); // size will have 4 after this statement is executed

Monday, 29 August 2016

Taking ownership of the memory from std::shared_ptr

There is no function in shared_ptr using that you take owner ship of the under lying pointer.

This may be because there might be multiple object which is referring to the same pointer.

shared_ptr has a constructor which takes an additional parameter which is used to delete the allocated object.

We will use this deleter to control the ownership.

A simple deleter implementation is shown below,
class Deleter {
private:
    std::shared_ptr<bool> mOwn = std::make_shared<bool>(true);

public:
    void setOwn(bool v) {
        *mOwn = v;
    }

    void operator()(Test *p) {
        if (*mOwn) {
            delete p;
        }
    }
};

Now we can use the above Deleter class to control the ownership of the pointer. An example use is shown below.
Deleter dltr;
std::shared_ptr<Test> obj1 = std::shared_ptr<Test>(new Test(), dltr);
dltr.setOwn(false);

std::shared_ptr<Test> obj2 = obj1;

delete obj2.get(); // safe to delete


We can specify the deleter when we reset the pointer as well.
Test *tobj1 = new Test();
Test *tobj2 = new Test();

Deleter dltr;
dltr.setOwn(false);
std::shared_ptr<Test> obj1 = std::shared_ptr<Test>(tobj1, dltr);
obj1.reset<Test, Deleter>(tobj2, dltr);

delete tobj1; // safe to delete
delete tobj2; // safe to delete