Segmentation fault (core dumped) run-time error

mystring.cxx 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
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
184
185
186
187
188
189
190
#include <iostream>
#include <cstring>
#include <cassert>
#include <cctype>
#include <stdlib.h>
#include "mystring.h"
using namespace std;

namespace main_savitch_4
{
    mystring::mystring(const char str[])
    {
        current_length = strlen(str);
        allocated = current_length + 1;
        sequence = new char[allocated];
        strcpy(sequence, str);
    }

    mystring::mystring(const mystring& source)
    {
        allocated = source.allocated;
        sequence = new char[allocated];
        current_length = source.current_length;
        strcpy(sequence, source.sequence);
    }

    mystring::~mystring()
    {
        delete [] sequence;
    }

    void mystring::operator +=(const mystring& addend)
    {
        if (current_length + addend.current_length > allocated - 1)
        {
            reserve(current_length + addend.current_length + 5);
        }

        strcat(sequence, addend.sequence);
        current_length = strlen(sequence);
    }

    void mystring::operator +=(const char addend[])
    {
        if (current_length + strlen(addend) > allocated - 1)
        {
            reserve(current_length + strlen(addend) + 5);
        }

        strcat(sequence, addend);
        current_length = strlen(sequence);
    }

    void mystring::operator +=(char addend)
    {
        if (current_length + 1 > allocated -1)
        {
            reserve(allocated + 1);
        }

        sequence [current_length] = addend;
        sequence [current_length + 1] = '\0';
        current_length = current_length + 1;
    }

    void mystring::reserve(size_t n)
    {
        char * new_array;

        if (n == allocated - 1)
        {
            return;
        }

        if (n < current_length + 1)
        {
            n = allocated;
        }

        new_array = new char[n];
        strcpy(new_array, sequence);
        delete [] sequence;
        sequence = new_array;
        allocated = n;
    }

    void mystring::operator =(const mystring& source)
    {
        char * new_sequence;

        if(this == &source)
        {
            return;
        }

        if(current_length != source.current_length)
        {
            new_sequence = new char[source.current_length];
            delete [] sequence;
            sequence = new_sequence;
            current_length = source.current_length;
        }

        allocated = source.allocated;
        copy(source.sequence, source.sequence + allocated, sequence);
    }

    char mystring::operator [](size_t position) const
    {
        assert(position < length());
        return sequence[position];
    }

    ostream& operator <<(ostream& outs, const mystring& source)
    {
        outs << source.sequence;
        return outs;
    }

    bool operator ==(const mystring& s1, const mystring& s2)
    {
        return (strcmp(s1.sequence, s2.sequence) == 0);
    }

    bool operator !=(const mystring& s1, const mystring& s2)
    {
        return (strcmp(s1.sequence, s2.sequence) != 0);
    }

    bool operator >=(const mystring& s1, const mystring& s2)
    {
        return (!(strcmp(s1.sequence, s2.sequence) < 0));
    }

    bool operator <=(const mystring& s1, const mystring& s2)
    {
        return (!(strcmp(s1.sequence, s2.sequence) > 0));
    }

    bool operator >(const mystring& s1, const mystring& s2)
    {
        return (strcmp(s1.sequence, s2.sequence) > 0);
    }

    bool operator <(const mystring& s1, const mystring& s2)
    {
        return (strcmp(s1.sequence, s2.sequence) < 0);
    }

    mystring operator +(const mystring& s1, const mystring& s2)
    {
        mystring result;
        result += s1;
        result += s2;
        return result;
    }

    istream& operator >>(istream& ins, mystring& target)
    {
        char c;

        while(ins && isspace(ins.peek()))
        {
            ins.ignore();
        }

        target = "";

        while(ins && !isspace(ins.peek()))
        {
            ins >> c;
            target += c;
        }
	return ins;
    }

    istream& getline(istream& ins, mystring& target)
    {
        char c;

        target = "";

        while(ins && (ins.peek() != '\n'))
        {
            ins.get(c);
            target += c;
        }
	return ins;
    }
}

stringexam.cxx 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
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
#include <iostream>    // Provides cin and cout
#include "mystring.h"  // Provides mystring class
using namespace std;
using namespace main_savitch_4;

enum comparison { EQUAL, NOTEQUAL, LE, GE, LESS, GREATER };
const string COMPARISON_NAMES[] = { "==", "!=", "<=", ">=", "<", ">" };
const int MANY = 6;
const string WORDS[] = {
    "t",
    "quick",
    "brown",
    "fox",
    "",
    "01234567890012345678900123456789001234567890012345678900123456789"
};

bool same(string s1, mystring s2)
{
    size_t i;

    if (s1.length( ) != s2.length( ))
	return false;

    for (i = 0; i < s1.length( ); ++i)
    {
	if (s1[i] != s2[i])
	    return false;
    }

    return true;
}

bool test_comparisons(string a1, string a2, comparison which)
{
    mystring s1(a1.c_str( ));
    mystring s2(a2.c_str( ));
    
    switch (which)
    {
    case EQUAL:    return ((a1 == a2) == (s1 == s2));
    case NOTEQUAL: return ((a1 == a2) == (s1 == s2));
    case LE:       return ((a1 == a2) == (s1 == s2));
    case GE:       return ((a1 == a2) == (s1 == s2));
    case LESS:     return ((a1 == a2) == (s1 == s2));
    case GREATER:  return ((a1 == a2) == (s1 == s2));
    }
    return false;
}

bool test_value_semantics(string s)
{
    mystring s1(s.c_str( ));
    mystring s2(s1);
    mystring s3;

    s3 = s2;
    return same(s, s1) && same(s, s2) && same(s, s3);
}

int main( )
{
    int passed;       // Number of tests passed in one part of the program
    int score = 0;    // Number of tests passed overall
    int total = 0;    // Number of tests run
    int i, j, which;  // Index counters
    string s;         // A string to test the += operator
    mystring mys; // A string to test the += operator
    mystring abc; // A string to test the += operator

    // Introductory message.
    cout << "This program runs a few tests on your string class.\n";
    cout << "Please note that all the tests use the length member\n";
    cout << "function and the operator [ ].\n" << endl;
    
    // Test the constructors and assignment operator:
    cout << "Testing constructors and assignments..." << endl;
    passed = 0;
    for (i = 0; i < MANY; ++i)
    {
	if (test_value_semantics(WORDS[i])) ++passed;
    }
    cout << "Passed " << passed << " out of " << MANY << "." << endl;
    score += passed;
    total += MANY;

    // Test the += operator
    cout << "Testing the += operators..." << endl;
    passed = 0;
    s += 'x';
    mys += 'x';
    if (same(s, mys)) ++passed;
    for (i = 0; i < MANY; ++i)
    {
	s += WORDS[i]; mys += WORDS[i].c_str();
	if (same(s, mys)) ++passed;
    }
    s += "abc";
    abc = "abc";
    mys += abc;
    if (same(s, mys)) ++passed;
    cout << "Passed " << passed << " out of " << MANY+2 << "." << endl;
    score += passed;
    total += MANY+2;

    // Test a self-assignment:
    cout << "Testing a self-assignment..." << endl;
    passed = 0;
    mys = mys;
    if (same(s, mys)) ++passed;
    cout << "Passed " << passed << " out of 1." << endl;
    score += passed;
    ++total;
    
    // Test a self +=:
    cout << "Testing a self application of the += operator..." << endl;
    passed = 0;
    s += s;
    mys += mys;
    if (same(s, mys)) ++passed;
    cout << "Passed " << passed << " out of 1." << endl;
    score += passed;
    ++total;
    
    // Test the Boolean operators
    for (which = EQUAL; which <= GREATER; ++which)
    {
	cout << "Testing the Boolean operator " 
	     << COMPARISON_NAMES[which] << "..." << endl;
	passed = 0;
	for (i = 0; i < MANY; ++i)
	    for (j = 0; j < MANY; ++j)
		if (test_comparisons(WORDS[i], WORDS[j], comparison(which)))
		    ++passed;
	if (passed == MANY*MANY)
	{
	    cout << "Passed 1 out of 1." << endl;
	    ++score;
	}
	else
	    cout << "Passed 0 out of 1." << endl;
	++total;
    }
	    
    // Print results
    cout << "Total for these little tests: "
	 << score << " out of " << total << "." << endl;

    return 0;
}


this program compiles but when i run it it works fine in till it gets to the part in the stringexam.cxx file named: //Test a self +=

when it gets to that test it crashes giving me the segmentation fault (core dumped) error. it seems to have something to do with my:

strcat(sequence, addend.sequence);

in the

void mystring::operator +=(const mystring& addend)

function. the strcat() works fine on the tests before the //Test a self += but again when it gets to that test it crashes. if i take it out it doesnt pass the tests that access the void mystring::operator +=(const mystring& addend) function, but everything else works.

can you tell me why it is giving me this error and point me in the direction of how to fix it.

thanks
You have a self-assignment problem.

s += s;

Since this == &addend, Line 39 is essentially

strcat( buffer, buffer );

ie, concatenating itself.

Topic archived. No new replies allowed.