Post incrementer for my own string class using doubly linked list

Hi, I am trying to implement post incrementer for my own string class using doubly linked list. I had no problem with pre-incrementer but somehow, I can't get post incrementer to work. It keeps crashing and I can't figure out why. The error says
"Exception thrown at 0x00F31EAE in Doubly Linked List and String.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC."
"Unhandled exception at 0x00F31EAE in Doubly Linked List and String.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC."

Please take a look at the code below.
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
  struct node
{
	node(const char& dataIn = char(), node* nextIn = nullptr, node* prevIn = nullptr)
		:data(dataIn),next(nextIn),prev(prevIn){}
	node* next;
	node* prev;
	char data;
};	
class myString
{
Public:
        myString operator ++(int);
private:
	node* headPtr;
	node* tailPtr;
	size_t ctr;
}
myString myString::operator++(int)
{
	myString copy; //Makes a copy to be returned
	listCopy(headPtr, copy.headPtr, copy.tailPtr);
	copy.ctr = ctr;
	node* temp = headPtr;
	while (temp != nullptr) //Increments the original
	{
		++temp->data;
		temp = temp->next;
	}
	return copy; // returns the copy
}
// Non member function
void listCopy(const node* sourceIn, node*& headIn, node*& tailIn) 
{
	if (sourceIn == nullptr)
		return;
	headInsert(headIn, sourceIn->data);
	tailIn = headIn;
	sourceIn = sourceIn->next;
	while (sourceIn != nullptr)
	{
		tailInsert(tailIn, sourceIn->data);
		sourceIn = sourceIn->next;
		tailIn = tailIn->next;
	}
}

I would suggest that you provide enough code to retproduce the problem. This code doesn't compile especially because of line 11. c++ is case sensitive.
Oh sorry, I misspelled it when I was copying the code here.
I am trying to build my own string class that does the same job as the standard string class.
So my code is quite big and I don't want to draw criticism by posting the entire code.
OK, here is a snippet of code that I think my post incrementer function touches. I believe the problem is somewhere in it .
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

// Header
struct node
{
	node(const char& dataIn = char(), node* nextIn = nullptr, node* prevIn = nullptr)
		:data(dataIn),next(nextIn),prev(prevIn){}
	node* next;
	node* prev;
	char data;
};	
class myString
{
public:
	myString();
	myString(const char* ptrIn);
	~myString();
	node* getHeadPtr()const;
	node* getTailptr()const;
	size_t getNodeCtr()const;
	myString& operator ++();
	myString operator ++(int);
	friend std::ostream& operator << (std::ostream& out, const myString& str);
private:
	node* headPtr;
	node* tailPtr;
	size_t ctr;
};
void headInsert(node*& headIn, const char& dataIn);
void tailInsert(node* tailIn, const char& dataIn);
void listCopy(const node* sourceIn, node*& headIn, node*& tailIn);
void clear(node*& headIn);
void headRemove(node*& headIn);

// Implementation

myString::myString():headPtr(nullptr),tailPtr(nullptr),ctr(size_t()) //Default constructor
{
}
myString::myString(const char* ptrIn) //Constructor that takes a pointer to a character arrray
{
	size_t nodeCtr = size_t();
	while (*(ptrIn + nodeCtr) != NULL) // pre-condition =character array must be null-terminated
		++nodeCtr;
	if (nodeCtr != 0)
	{
		headInsert(headPtr, *ptrIn);
		tailPtr = headPtr;
		++ctr;
		while (ctr != nodeCtr)
		{
			tailInsert(tailPtr, *(ptrIn + ctr));
			tailPtr = tailPtr->next;
			++ctr;
		}
	}
}
myString::~myString() //Destructor
{
	clear(headPtr);
}
// Getters
node* myString::getHeadPtr()const 
{
	return headPtr;
}
node* myString::getTailptr()const
{
	return tailPtr;
}
size_t myString::getNodeCtr()const
{
	return ctr;
}
myString& myString::operator++() //Pre-incremeter that works fine
{
	node* temp = headPtr;
	while (temp != nullptr)
	{
		++temp->data;
		temp = temp->next;
	}
	return *this;
}
myString myString::operator++(int) //Post-incrementer that throws an error
{
	myString copy; // creates a temp to be returned 
	listCopy(headPtr, copy.headPtr, copy.tailPtr);  //copies data into the temp("Copy")
	copy.ctr = ctr;  //Updates the size of the temp("Copy")
	node* temp = headPtr;
	while (temp != nullptr)  // Updates the original data
	{
		++temp->data;
		temp = temp->next;
	}
	return copy;
}
std::ostream& operator<<(std::ostream& out, const myString& str) 
{
	node* temp = str.headPtr;
	while (temp != nullptr)
	{
		out << temp->data;
		temp = temp->next;
	}
	return out;
}
//Non-member functions
void headInsert(node*& headIn, const char& dataIn)
{
	if(headIn == nullptr)
		headIn = new node(dataIn);
}
void tailInsert(node* tailIn, const char& dataIn)
{
	if(tailIn->next == nullptr)
		tailIn->next = new node(dataIn,tailIn->next,tailIn);
}
void listCopy(const node* sourceIn, node*& headIn, node*& tailIn)
{
	if (sourceIn == nullptr)
		return;
	headInsert(headIn, sourceIn->data);
	tailIn = headIn;
	sourceIn = sourceIn->next;
	while (sourceIn != nullptr)
	{
		tailInsert(tailIn, sourceIn->data);
		sourceIn = sourceIn->next;
		tailIn = tailIn->next;
	}
}
void clear(node*& headIn)
{
	while (headIn != nullptr)
		headRemove(headIn);
}
void headRemove(node*& headIn)
{
	node* removePtr = headIn;
	headIn = headIn->next;
	delete removePtr;
}
Last edited on
It is actually hard to tell without chance to test.

But my guess is that the problem is 'shallow copy':

https://en.wikipedia.org/wiki/Object_copying

It seem you have no assignment operator for deep copy. Hence when one string is assigned to another (maybe temporary) the pointers become invalid as soon as the object copied from is destroy.
Topic archived. No new replies allowed.