About two and a half years ago, i would have never imagined myself writing anything about pointers or let alone be at a stage where i am no longer intimidated by them, but here i am blogging about using them. This is after almost 2 years of disliking it……well 2 years to actually get the hang of it and use them properly and honestly it now makes so much sense and i get an idea of the power of unmanaged code (of course when done properly).

Coming from the managed world (Java, Python and to some extent C#), it was quite a task for me to get grips with managing memory, even now i won’t say i have mastered the art of memory management in C++, but i am reasonably comfortable with it. The point i am trying to make is, watching out for memory isn’t second nature to my programming style….I still need to be on absolute alert when i am writing any C++ code, especially when i am passing pointers around the code. However having said all of that, writing some C++ code in vim, debugging it by writing stuff to the console and compiling it using a makefile does provide an unparalleled amount of geek satisfaction. I cannot believe that i actually sound like i am enjoying coding in C++…..but hey it is what it is.
Ok so now onto the real stuff, while coding C++, i often  need a chart of sorts to keep it all together….so i written some base code below which often helps me remember things in case i forget.

Problem

Using pointers and references with C++

Solution

The C++ class below should give an account of some of the possible usages of memory

void changing_with_passby_val(int& value){
//assign a new value
value = 42;
}
/*
 * Change the value which the pointer is pointing to
 * within a function
 **/
void change_value(int* ptr){

int value = 45;
/*remember we need to change the value that the pointer
* is pointing to and not the value of the pointer itself
* hence lets not make a mistake of doing this
* ptr = value
*/
*ptr = value;
}
int main()
{
/*
* first lets create a simple int pointer
* allocating memory with new is the c++ way
* if you are doing C, the malloc function
* is another way to do this
**/
int* ptrVal = new int;

/* now that we have a pointer, lets store a value to where we are pointing at*/
*ptrVal = 12;
cout<<“initial value:”<<*ptrVal<<endl;

/* now lets change the value we are pointing to */
change_value(ptrVal);
cout<<“What value are we point to now?:”<<*ptrVal<<endl;

/* well there is one other way in which we can change it */
int otherValue = 70;
/* the actual value of the pointer i.e. the address
  is being changed to the address of the variable “otherValue” */
ptrVal = &otherValue;
cout<<“Result of our change:”<<*ptrVal<<endl;

/* i am still not satisfied, lets try changing it one other way */
changing_with_passby_val(*ptrVal);
cout<<“Result of our change:”<<*ptrVal<<endl;

/*now before we move on to something else, letstry deleting our
* pointers and reinitializing them since we are managing our own
* memory, we must and we seriously must remember to clean it up
*/
//delete ptrVal;
/*hmm lets try accessing ptrVal now, the line below should result in
a very unpleasent segfault(invalid pointer) error
cout<<“Accessing after deletion”<<*ptrVal<<endl;*/

return 0;
}

ok so now lets do something more fun lets create a 2D int array with a pointer coming from Java, the first thing i would try would be  int [][] array2d;  However pointers in C++ opens up another means of doing this.

void create_2D_array()
{
int rows =2; int cols = 2;
/*what we are doing here is that we are assigning creating an int
* pointer and we are allocating 4 congatious memory locations for
* it.
*/
int* array2D = new int[rows*cols];
/*ok so we have our 2D array now, so lets fill it up with some
* random values from 1 to 10
*/
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
//cout<<rand()%10<<endl;
array2D[rows*i+j] = rand()%10;
}
}
/*great we have populated an array, now lets see what we actually put
* into it, now we can either access the elements the same way as we
* did above or, we can also do it with just 1 loop instead of 2 loops
*/
for(int i=0;i<(rows*cols);i++)
{
//since the values are stored in contagious blocks, we can just
//access them individually by their positions in the array
cout<<“array value at “<<i<<“:”<<array2D[i]<<endl;
}
}

Cool, so what next? ok i know what, so  if you have a large enough application and you know there is an object that you wont be using for a certain time period, then there is no point of keeping it in memory, especially when memory is limited. Hence in C++ you can delete  it for the time being and re-use it when needed.  Now i my case the application wasn’t large, however the existing objects were fairly large and i had a particular data structure, which i would use once , delete it and after a while reinitialize it with some new data. Sounds simple? well the concept isn’t that complicated but the implementation can be, i mean since i come from the managed world, i often had trouble keeping track of where what was being used/deleted and combine that with async stuff happening in the application that kept getting bigger!….ahh good times!!!!

void delete_and_reuse()
{
/* lets create a pointer to a vector of ints */
vector<int>* nums = new vector<int>;
/* lets fill it up with some values */
nums->push_back(40);
nums->push_back(2);
/* lets check the size and the first element in our vector pointer */
cout<<“size of the vector:”<<nums->size()<<endl;
cout<<“first val in our vector*:”<<nums->at(0)<<endl;
/* ok now lets destroy what we created */
delete nums;
/* and rebuild what we destroyed */
nums = new vector<int>;
/* lets populate it with some value and confirm what we added */
nums->push_back(43);
cout<<“value in the new vector pointer:”<<nums->at(0)<<endl;
}

References used


Leave a Reply

Your email address will not be published. Required fields are marked *