Program bombs out after I ever the value for x

The header file & Implementation is exactly as it is the textBook
The exercise is only to write the main program to test copy constructor.

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
  class pointerDataClass
{
public:
    void print() const;
		//Function to output the value of x and
		//the value of the array p
    void setData();
		//Function to input data into x and
		//into the array p
    void destroyP();
		//Function to deallocate the memory space
		//occupied by the array p

    pointerDataClass(int sizeP = 10);
		//constructor
		//Creates an array of the size specified by the
		//parameter sizeP; the default array size is 10

    ~pointerDataClass();
		//destructor
		//Deallocates the memory space occupied by the array p

    pointerDataClass (const pointerDataClass& otherObject);
		//copy constructor

private:
    int x;
    int lenP;
    int *p;		//pointer to an int array
};

the implementation
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
#include <iostream>
#include <cassert>

#include "pointerDataClass.h"

using namespace std;

void pointerDataClass::print() const
{
	cout<<"x = "<<x<<endl;

	cout<<"p = ";

	for(int i = 0; i < lenP; i++)
		cout<<p[i]<<" ";
	cout<<endl;
}

void pointerDataClass::setData()
{
	cout<<"Enter an integer for x: ";
	cin>>x;
	cout<<endl;

	cout<<"Enter "<<lenP<<" numbers: ";

	for(int i = 0; i < lenP; i++)
		cin>>p[i];

	cout<<endl;
}

void pointerDataClass::destroyP()
{
	lenP = 0;
	delete [] p;
	p = NULL;
}

pointerDataClass::pointerDataClass(int sizeP)
{
	x = 0;

	if(sizeP <= 0)
	{
		cout<<"Array size must be positive"<<endl;
		cout<<"Creating an array of size 10"<<endl;

		lenP = 10;
	}
	else
	lenP = sizeP;

	p = new int[lenP];
	assert(p != NULL);
}

pointerDataClass::~pointerDataClass()
{
	delete [] p;
}

	         //copy constructor
pointerDataClass::pointerDataClass
 	           (const pointerDataClass& otherObject)
{
	x = otherObject.x;

	lenP = otherObject.lenP;
	p = new int[lenP];
	assert(p != NULL);

	for(int i = 0; i < lenP; i++)
		p[i] = otherObject.p[i];
}

finally this is my main program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include "pointerDataClass.h"
using namespace std;

int main()
{
    pointerDataClass *list1, *list2;

    list1->setData();

    list1 = list2;

    cout << endl << "list1 = " ;
    list1->print() ;
    cout << endl;
    cout << "list2 = ";
     list2->print();
     return 0;

}

here is my output:
1
2
3
4
nter an integer for x: 5

rocess returned 255 (0xFF)   execution time
ress any key to continue.
I bet your main() program doesn't come from a text book!

Try:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    pointerDataClass list1, list2;   // Use ordinary variables, not pointers; you have nothing to point at

    list1.setData();

    list2 = list1;          // NOT list1 = list2

    cout << endl << "list1 = " ;
    list1.print() ;
    cout << endl;
    cout << "list2 = ";
     list2.print();
     return 0;
}
Last edited on
The header file & Implementation is exactly as it is the textBook

It does not follow Rule of Three/Five/Zero: https://en.cppreference.com/w/cpp/language/rule_of_three
(The Five can be excused if the book predates C++11.)

I hope that you don't believe the book's code to be in style that you should learn.

The exercise is only to write the main program to test copy constructor.

I don't see invocation of copy constructor. (OP's code calls no constructors at all.)

Lastchance calls copy assignment, which due to lack of Rule of Three shall explode.
1
2
3
4
5
6
pointerDataClass list1
pointerDataClass list2;
list2 = list1;
// versus
pointerDataClass list1
pointerDataClass list2 = list1;
Last edited on
The exercise was or is to write the main driver program to test the copy constructor lastchance.
So it definetly does not come from the text book.
It is written by me.

Somehow it bombs out after I type the value of x

I will try your main program soon
Mmm, apologies. @Keskiverto is right. Should be
pointerDataClass list2 = list1;
to copy on construction rather than
list2 = list1;
(with earlier declaration of list2).

Seemingly got away with it in C++ shell in this instance.
Your main driver program works fine lastchance but I was under the impression that pointers should be used because the chapter3 is dealing with pointers. I would appreciate if you could write it using pointers
Bopaki wrote:
Your main driver program works fine lastchance

Actually, it doesn't (or probably wouldn't if you tried to do much more with list1 and list2). See @Keskiverto's post for the proper information.

I suspect that the usage of pointers is confined to how they are used to access unnamed memory on the heap (where you are using "new" and "delete") rather than in your main program.

I'll try to rewrite main() with pointers EDIT. Scrub that, with the existing constructors that is asking for trouble!
Last edited on
In case you want to use pointers, just remember you need to guarantee a pointer is actually pointing to a valid memory area before using it.

Hints:
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <cassert>
#include <iostream>


class PointerDataClass {
public:
    explicit PointerDataClass(int len_p_arg = 10);
    PointerDataClass(const PointerDataClass& other);
    PointerDataClass& operator=(const PointerDataClass& other);
    PointerDataClass(PointerDataClass&& other);
    PointerDataClass& operator=(PointerDataClass&& other);

    void print() const;
    void destroyP();
    void setData();

    ~PointerDataClass();

private:
    int x;
    int len_p;
    int* p;
};


PointerDataClass::PointerDataClass(int len_p_arg)
{
    x = 0;
    len_p = len_p_arg;
    if(len_p_arg <= 0)
    {
        std::cout << "Array size must be positive.\n"
                     "Creating an array of size 10.\n";
        len_p = 10;
    }

    p = new int[len_p] {};
    assert(p != nullptr);
}


// Copy constructor:
PointerDataClass::PointerDataClass(const PointerDataClass& other)
{
    x = other.x;
    len_p = other.len_p;
    p = new int[len_p];
    assert(p != nullptr);

    for(int i = 0; i < len_p; i++) {
        p[i] = other.p[i];
    }
}


// Copy assignment operator:
// (not copy&swap idiom)
PointerDataClass& PointerDataClass::operator=(const PointerDataClass& other)
{
    if(this == &other) { return *this; }

    x = other.x;
    len_p = other.len_p;
    p = new int[len_p];
    assert(p != nullptr);

    for(int i = 0; i < len_p; i++) {
        p[i] = other.p[i];
    }

    return *this;
}


// Move constructor:
PointerDataClass::PointerDataClass(PointerDataClass&& other)
{
    x = other.x;
    other.x = 0;

    len_p = other.len_p;
    other.len_p = 0;

    p = other.p;
    other.p = nullptr;
}


// Move assignment operator:
PointerDataClass& PointerDataClass::operator=(PointerDataClass&& other)
{
    if(this == &other) { return *this; }

    delete [] p;

    x = other.x;
    other.x = 0;

    len_p = other.len_p;
    other.len_p = 0;

    p = other.p;
    other.p = nullptr;
    return *this;
}


PointerDataClass::~PointerDataClass()
{
    delete [] p;
}


void PointerDataClass::print() const
{
    std::cout << "x = " << x
              << "; p = ";
    for(int i = 0; i < len_p; ++i) {
        std::cout << p[i] << ' ';
    }
    std::cout << '\n';
}


void PointerDataClass::setData()
{
    std::cout << "Enter an integer for x: ";
    std::cin >> x;

    std::cout << "Enter " << len_p << " numbers: ";
    for(int i = 0; i < len_p; ++i) {
        std::cin >> p[i];
    }
}


void PointerDataClass::destroyP()
{
    delete [] p;
    p = nullptr;
    len_p = 0;
}


int main()
{
    PointerDataClass* list1;
    // Now list1 is pointing to an unknown memory area.
    // It means that area could be read only or reserved or... whatever.
    // You should not do anything with a pointer until you have made it
    // point to a memory area you own!
    list1 = new PointerDataClass();
    // Now list1 is pointing to a valid memory area.
    // You can operate on that memory area:
    list1->setData();

    // Since there's an assignment in it, the following line is to be read
    // from right to left (the operations on the right of the assignments
    // are executed before the once on the left):
    // 1) A memory area is allocated for you;
    // 2) the content of that memory area is copied from the memory area
    //    pointed to by list1 (thanks to the overloaded copy constructor);
    // 3) a new pointer named list2 is created;
    // 4) list2 is assigned the address of the newly created memory area:
    PointerDataClass* list2 = new PointerDataClass(*list1);

    std::cout << "list1 = " ;
    list1->print() ;

    std::cout << "\nlist2 = ";
    list2->print();

    std::cout << '\n';

    delete list2;   // release the allocated memory
                    // (Note: the destructor can't be protected)
    list2 = nullptr;    // make sure the pointer doesn't point any more
                        // to the previous (now deallocated) memory area

    delete list1;
    list1 = nullptr;
    return 0;
}


Output:
Enter an integer for x: 666
Enter 10 numbers: 9 8 7 6 5 4 3 2 1 0
list1 = x = 666; p = 9 8 7 6 5 4 3 2 1 0

list2 = x = 666; p = 9 8 7 6 5 4 3 2 1 0

I know that the book won't teach it, but users of C++ should know the smart pointers:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
    // lets not create uninitialized pointers.  Ever.
    // lets not use raw pointers
    auto list1 = std::make_unique<PointerDataClass>();
    list1->setData();

    auto list2 = std::make_unique<PointerDataClass>( *list1 );

    std::cout << "list1 = " ;
    list1->print() ;
    std::cout << "\nlist2 = ";
    list2->print();
    std::cout << '\n';

    // the std::unique_ptr handles the deallocations
    return 0;
}

The example class is very limited. It does not support demonstrating that the copy constructed object truly is a distinct deep copy and not a shallow copy that leads to double deletes.
Thank you all good people.
The introduction of the little 3 character word "new" solved my problem.

1
2
 
	p = new int[lenP];

after typing in that line, the program worked very well
Topic archived. No new replies allowed.