[Unspecified Crash] Move Semantics

Hello Community,

I've been typing in the following example code from a book, which is shown in the following, demonstrating move semantics. It works up to the point where the desctructor message is output to screen, then crashes.

I could not determine what the course for this crash is, there is no other message shown than the window saying: Program has stopped working, and the logs give no indication as to where the error occurs or why.

So, my question is, what could be the source of the error? (My guess is that it has to do with strcpy (using strcpy_s does not solve the error, the program keeps crashing after call to destructor)). (Ex.: strcpy_s(name, strlen(obj.name), obj.name);)

The 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
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
#ifndef PERSON_H_
#define PERSON_H_

#include <iostream>
using std::cout;

#include <cstring>

class Person
{
	private:
		char *name;

	public:
		// Default constructor
		Person()
		{
			cout << "*** default constructor ***\n";
			name = nullptr;
		}

		// Constructor with a parameter
		Person(char *n)
		{
			cout << "*** parameterized constructor ***\n";
			name = new char[strlen(n) + 1];
			strcpy(name, n);
		}

		// Copy constructor
		Person(const Person &obj)
		{
			cout << "*** copy constructor ***\n";
			name = new char[strlen(obj.name) + 1];
			strcpy(name, obj.name);
		}

		// Destructor
		~Person()
		{
			cout << "*** destructor ***\n";
			delete [] name;
		}

		// Overloaded = operator
		Person & operator = (const Person &right)
		{
			cout << "*** assignment operator ***\n";
			if (this != &right)
			{
				if (name != nullptr)
				{
					delete [] name;

					name = new char[strlen(right.name) + 1];
					strcpy(name, right.name);
				}
			}
			return *this;
		}

		// getName member function
		char *getName() const
		{ return name; }
};

#endif 


The Source 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
/* PersonDm.cpp - This program demonstrates a class's move semantics capabilities. */

#include "Person.h"

#include <iostream>
using std::cout;

#include <cstring>
//using std::string;

// Function prototype
Person makePerson();

void displayPerson(Person);

int main()
{
	Person person;
	person = makePerson();
	displayPerson(person);

	return 0;
}

Person makePerson()
{
	Person p("Will MaKenzie");
	return p;
}

void displayPerson(Person pTwo)
{
	cout << pTwo.getName() << "\n";
}

The problem is at line 51 in the header file:
51
52
53
54
55
56
57
    if (name != nullptr)
    {
        delete [] name;

        name = new char[strlen(right.name) + 1];
        strcpy(name, right.name);
    }


What happens if name == nullptr?

A related problem, what happens in function displayPerson() if the name is a nullptr?

e.g.
1
2
    Person q;
    displayPerson(q);



Edit: sorry - I must not have been awake when I started to reply.
1
2
3
4
5
6
7
8
9
10
11
12
13
    // Copy constructor
    Person(const Person &obj)
    {
        cout << "*** copy constructor ***\n";

        if (obj.name != nullptr)
        {
            name = new char[strlen(obj.name) + 1];
            strcpy(name, obj.name);
        }
        else
            name = nullptr;
    }
Last edited on
Chervil, thank you for helping me! Unfortunately the copy constructor was not the problem. It was the overloaded assignment operator function, which in the book looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
	// Overloaded = operator
		Person & operator = (const Person &right)
		{
			cout << "*** assignment operator ***\n";
			if (this != &right)
			{
				if (name != nullptr)
				   delete [] name;
				name = new char[strlen(right.name) + 1];
				strcpy(name, right.name);
			}
			return *this;
		}


Because there are no brackets separating the if statement, and I not paying attention to the indentation, put brackets underneath the inner if-clause, enclosing all three lines marked above ...

Thus, the problem is solved, lesson learned, and improvement as per your suggestion implemented. :-)
Unfortunately the copy constructor was not the problem.

But it is a problem, maybe not the one you were focussing upon.

If you try to copy a default-initialised Person where name == nullptr, what do you think the strlen() and strcpy() functions will do?

existing code:
1
2
3
4
5
6
7
		// Copy constructor
		Person(const Person &obj)
		{
			cout << "*** copy constructor ***\n";
			name = new char[strlen(obj.name) + 1];
			strcpy(name, obj.name);
		}
Registered users can post here. Sign in or register to post.