Jason
Jason

Reputation: 2288

c++ pointer arithmetic and classes

So I just started learning about pointer arithmetic and I was fiddling around with some of its capabilities. Once I started trying to fool around with pointer arithmetic and classes, I came to a problem. I wrote the following code below:

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;


class Cat
{
public:
    Cat();
    ~Cat();
    int GetAge() { return itsAge; }
    void SetAge(int age) { itsAge = age; }

private:
    int itsAge;

};

Cat::Cat()
{
}

Cat::~Cat()
{
}

int _tmain(int argc, _TCHAR* argv[])
{

    Cat *Family = new Cat[5];
    Family = Family + 1;
    Family->SetAge(3);
    cout << Family[1].GetAge()<< endl;

    return 0;
}

In my mind, I'm creating a pointer called Family which will point to an array of Cat objects. This pointer will represent the address of Family[0]. Then, on the next line, I have pointer Family point to a new address by adding 1 to the pointer itself (so the compiler should take this as moving up an address slot to the next element in the array, Family[1]). Then I set the age to 3 and try and output the value of Family[1]'s age, however the answer I get is -842150451 and not 3. What am I missing?

Upvotes: 3

Views: 1382

Answers (5)

CreativeMind
CreativeMind

Reputation: 917

Please see the comments in code below :

#include <iostream>
#include <string>
using namespace std;

class Cat
{
public:
    Cat();
    ~Cat();
    int GetAge() { return itsAge; }
    void SetAge(int age) { itsAge = age; }

private:
    int itsAge;
};

Cat::Cat() : itsAge(0)
{
}

Cat::~Cat()
{
}

int main(int argc, char* argv[])
{

    Cat *cats = new Cat[5];
    for( int i = 0; i < 5; ++i )
    {
      cats[i].SetAge( i + 1 );
    }

    //Here cats points to the first cat so, it will print 2
    cout << cats[1].GetAge()<< endl;

    //Now cat will be pointing to second cat as pointer will be moved forward by one
    cats = cats + 1;

    //below statement will print 3, as cats[0] is pointing to 2nd cat, and cats[1] will be pointing to 3rd cat
    cout << cats[1].GetAge()<< endl;

    return 0;
}

Upvotes: 1

TryinHard
TryinHard

Reputation: 4118

Please note that when you increment the Family,

Family = Family + 1;

Family points to a location corresponding to Cat[1]. Now you set age of the Cat[1] using:

Family->SetAge(3);

But in next statement you get the value from Family[1] which points to Cat[2] actually:

cout << Family[1].GetAge()<< endl;

Thus, it prints the garbage as Family[1] is equivalent to *(Family+1) i.e. incrementing it again.

Instead you can use Family->GetAge():

Cat *Family = new Cat[5];   
Family = Family + 1; 
Family->SetAge(3);
cout << Family->GetAge()<< endl;

Also keep habit of using delete for the dynamic allocations to prevent memory-leaks.

Upvotes: 2

R Sahu
R Sahu

Reputation: 206717

I see couple of issues:

  1. itsAge is not initialized in the constructor of the class. Change it to:

    Cat::Cat() : itsAge(0)
    {
    }
    
  2. Your understanding of pointer arithmetic is slightly flawed.

    You have:

    Cat *Family = new Cat[5];   // Family points to the first Cat
    Family = Family + 1;        // Now Family points to the second Cat
    Family->SetAge(3);          // Set the age of the second Cat
    
    cout << Family[1].GetAge()<< endl; // Since Family points to the
                                       // second object, Family[0] is the
                                       // second object. Family[1] is the third
                                       // object, not the second object.
                                       // That is the misunderstanding
    

Upvotes: 4

bhzag
bhzag

Reputation: 2980

Try:

Cat *Family = new Cat[5];
(Family + 1)->SetAge(3);
cout << Family[1].GetAge()<< endl;

Upvotes: 1

mat_geek
mat_geek

Reputation: 2511

itsAge is not initialised as you haven't set it in the default constructor. It is currently garbage.

Cat::Cat()
: itsAge(0)
{
}

This becomes a problem as Family[1] points to the Cat after the one you initialised. Pointer[1] is the equivalent of *(Pointer + 1).

Upvotes: 6

Related Questions