Reputation: 2288
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
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
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
Reputation: 206717
I see couple of issues:
itsAge
is not initialized in the constructor of the class. Change it to:
Cat::Cat() : itsAge(0)
{
}
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
Reputation: 2980
Try:
Cat *Family = new Cat[5];
(Family + 1)->SetAge(3);
cout << Family[1].GetAge()<< endl;
Upvotes: 1
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