Pointer Data Corruption?

Hello,

I am working on a simple program that declares two DynamicInt class objects in the driver, one with an argument and one without. Included in my implementation code is commenting I was using to display the values of the pointer that is the only member variable in the DynamicInt class. Upon initialization the values appear to be correct. However, immediately following the initialization the value being pointed to be the pointer appears corrupt/garbage when I call the getData() function which simply returns the value of the pointer ptr.

I can't figure out what is causing this value to change...

Any help is appreciated. I also have a feeling my destructor is set up incorrectly, at the moment the body is empty because it was creating run-time crashes : /




HEADER FILE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#ifndef DYNAMIC_INT
#define DYNAMIC_INT
#include <iostream>
using namespace std;


class DynamicInt
{

private:
	
	int *ptr;		//dynamic data member
	
public:

	//default constructor
	DynamicInt();
	
	//constructor
	DynamicInt(int m);

	//destructor
	~DynamicInt();

	//overloaded assignment operator
	DynamicInt operator= (const DynamicInt& rhs);

	//copy constructor
	DynamicInt(const DynamicInt& obj);

	//returns the value of the dynamic data member
	int getData();

	//output stream operator << as a friend function
	friend ostream& operator<< (ostream& ostr, const DynamicInt& obj);

	//function to take in a DynamicInt object, add 5 to it's dynamic data member, and then reurn the new local object
	friend DynamicInt f(DynamicInt obj);

};
#endif  







CPP/IMPLEMENTATION FILE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "DynamicInt.h"
#include <iostream>
using namespace std;




//default constructor
DynamicInt::DynamicInt()
{
	int z = 0;

	ptr = &z;			//set the dynamic data member to zero

	cout << "\n\naddress of z " << &z;
	cout << "\nvalue of *ptr " << *ptr;
	cout << "\nvalue of ptr " << ptr;
}




//constructor
DynamicInt::DynamicInt(int m)
{
	ptr = &m;			//set the dynamic member data with m

	cout << "\n\naddress of m " << &m;
	cout << "\nvalue of *ptr " << *ptr;
	cout << "\nvalue of ptr " << ptr;
}




//destructor
DynamicInt::~DynamicInt()
{
	//delete ptr;
}




//copy constructor
DynamicInt::DynamicInt(const DynamicInt& obj):ptr(obj.ptr)
{
	//allocate dynamic memory and initialize it with value *obj.ptr
	ptr = new int(*obj.ptr);

	//if no dynamic memory is available, throw error
	if (ptr == NULL)
		throw ("\nDynamicInt Copy Constructor: Memory Allocation Failure\n");
}




//overloaded << operator
ostream& operator<< (ostream& ostr, const DynamicInt& obj)
{
	//output the data value *ptr
	ostr << "\n" << *obj.ptr << "\n";

	//return the ostream object
	return ostr;
}



//overloaded assignment operator
DynamicInt DynamicInt::operator= (const DynamicInt& rhs)
{
	*ptr = *rhs.ptr;		//assign rhs dynamic data value to the dynamic data value of this object

	return *this;			//return the current object
}





//take in a DynamicInt object, add 5 to it's dynamic data member, and then reurn the new local object
DynamicInt f(DynamicInt obj)
{
	//create a new local DynamicInt object and sets the dynamic data member 
	//to 5 plus the value of the argument object's data member value
	DynamicInt localObj(5 + obj.getData());

	cout << "\nobj.ptr -----> " << obj.ptr;

	return localObj;			//return the locally created object
}



//return the value of the dynamic data member
int DynamicInt::getData()
{
	cout << "\n\nvalue of *ptr is " << *ptr;
	cout << "\nvalue of ptr is " << ptr;

	return *ptr;	//return the value of the dynamic data member
}








DRIVER/MAIN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <stdlib.h>
#include "DynamicInt.h"

using namespace std;

int main()
{
	cout << "\nTest 0";
	
	DynamicInt obj1(10);
	DynamicInt obj2;

	cout << "\n\nobj1.getData() ----> " << obj1.getData();

	cout << "\n\nTest 1\n\n";

	obj2 = f(obj1);				//call the f function

	cout << "\n\nTest 2\n\n";
	cout << obj2.getData();		//output the dynamic data member in obj2


	cout << endl << endl;										//blank lines for formatting
	return 0;													//end the program
}




















You are failing to understand pointers.

Look at your default constructor:

1
2
3
4
5
6
7
8
9
10
DynamicInt::DynamicInt()
{
	int z = 0;

	ptr = &z;			//set the dynamic data member to zero

	cout << "\n\naddress of z " << &z;
	cout << "\nvalue of *ptr " << *ptr;
	cout << "\nvalue of ptr " << ptr;
}


Here's what's happening.

1) You're creating a local variable 'z' and assigning it to zero
2) You're assigning ptr to point to 'z'.

Note: this does not mean 'ptr' points to zero. Nor does it mean pointer is zero. It means pointer points to z.

The problem is, 'z' goes out of scope at the end of the function and gets destroyed, but 'ptr' still points to it, meaning 'ptr' becomes a bad pointer (ie: what it points to no longer exists, so it points to nothing / garbage memory)

This is bad bad bad bad.

Your other constructor has the same problem:

1
2
3
4
5
6
7
8
DynamicInt::DynamicInt(int m)
{
	ptr = &m;			//set the dynamic member data with m

	cout << "\n\naddress of m " << &m;
	cout << "\nvalue of *ptr " << *ptr;
	cout << "\nvalue of ptr " << ptr;
}


'm' is local to this ctor, so as soon as the ctor returns, 'm' no longer exists, which means 'ptr' no longer points to valid memory!

On the other hand, your copy ctor is correct. By allocating the memory with new, the memory you're pointing to exists until you delete it (ie: it does not get destroyed when the function exits).

But, since you're not deleteing the memory (your dtor has that commented out), you have memory leaks.

Also the assignment operator should return DynamicInt& not DynamicInt (ie, it should return a reference to *this, not a copy of *this)
Last edited on

Thank you, I forgot that I had to create the pointers using the 'new' reserved word, which is what creates the dynamic memory. This explains also why the destructor was creating errors during run-time... it was trying to delete memory that was never allocated on the heap.

Last edited on
Topic archived. No new replies allowed.