When initializing a pointer to allocate memory in the heap, should we specify the type as a pointer? That is, should it be:
int* ptr = new num;
OR
ptr = new num;
Both seem to work, and I was under the impression that the first method is better, but doing it is causing some issues in my code below.
I have a class with two member variables, both of which should be pointers to a new int on the heap. When the copy constructor is invoked, it should allocate new memory in the heap, but copy the values of the ints to which the pointers of the argument being passed in are pointing.
#include <iostream>
using namespace std;
// Header file
#pragma once
class numPair {
public:
int *pa,*pb;
numPair(int, int);
numPair(const numPair &);
};
// Implementation file
#include "Cube.h"
#include <iostream>
using namespace std;
numPair::numPair(int a, int b) {
cout << "Constructor invoked!" << endl;
int* pa = new int(a);
cout << "pa = " << pa << endl;
cout << "*pa = " << *pa << endl;
int* pb = new int(b);
cout << "pb = " << pb << endl;
cout << "*pb = " << *pb << endl;
}
numPair::numPair(const numPair& other) {
cout << "Copy invoked!" << endl;
int* ptr = other.pa;
cout << "ptr in copy: " << ptr << endl;
}
// main.cpp file
#include "Cube.h"
#include <iostream>
using namespace std;
int main() {
numPair p(15,16);
cout << "p.pa = " << p.pa << endl;
numPair q(p);
numPair *hp = new numPair(23, 42);
delete hp;
return 0;
}
The output of the main.cpp file is:
Constructor invoked!
pa = 0x5594991a7280
*pa = 15
pb = 0x5594991a72a0
*pb = 16
p.pa = 0x3
Copy invoked!
ptr in copy: 0x3
Constructor invoked!
pa = 0x5594991a72e0
*pa = 23
pb = 0x5594991a7300
*pb = 42
As can be seen, when the constructor is invoked, the pa
and pb
are both valid memory addresses to ints holding the values 15 and 16. However, once the constructor has finished executing, if I try to access the value of p.pa
, it returns 0x3, instead of the memory address from before. This is, of course, a problem on its own and also leads to issues with the copy constructor.
I've found two ways of fixing this.
The first is to change the definition of the constructor by removing the type of
pa
andpb
. That is changingint* pa = new int(a);
topa = new int(b)
. Repeat the same forpb
. Now, p.pa returns the correct memory address.The second is by commenting out the initialisation and deletion of
hp
. That is, removing these lines from themain()
function:
numPair *hp = new numPair(23, 42);
delete hp;
I don't really understand why specifying the type of a pointer is causing these errors or, in fact, why the memory addresses for p.pa
and p.pb
are having errors because of the initialization of another instance of the class, especially when considering the fact that hp
is initialized after p
.