*** glibc detected *** double free or corruption

Hi. I'm trying to test an implementation of my String class. My test code ends with a success print, but afterwards I get a glibc detected error once the test code terminates. I have no clue what I did wrong in the code. Any help is appreciated. The following is the header file, the source code and the test code, respectively.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Header file -String.h

#ifndef STRING_H
#define STRING_H

class String {
        int size;
        char * buffer;
public:
        String();
        String(const String &);
        String(const char *);
        ~String();

	int length()const;
	void resize(int, char);
	char& operator[](unsigned int);
	bool operator==(const char*);
	bool operator==(String&);
	void operator+=(const char*);
	void operator=(const char*);
};
#endif 

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
//Source code - String.cpp
#include "String.h"
#include <cstring>

using namespace std;

String::String() {
	buffer=0;	
	resize(0, ' ');
}

String::~String() {
	delete [] buffer;
}

String::String(const String& Str) {
	buffer = 0;
	resize(Str.length(), ' ');
	strcpy(buffer, Str.buffer);
}

String::String(const char* cp) {
	buffer = 0;
	resize(strlen(cp), ' ');
	int i=0;
	while(cp[i]!='\0'){
		buffer[i]=cp[i];
		i++;
	}
}

int String::length() const{
	return size;
}
void String::resize(int newSize, char pad) {
	if (buffer == 0)
		size = 0;
	if (newSize < size){
		return;
	}
	else {
		int i;
		char* newBuffer = new char[newSize];
		for (i=0; i<size && buffer[i]!=0; i++){
			newBuffer[i] = buffer[i];
		}
		for (; i<newSize; i++){
			newBuffer[i] = pad;
		}
		delete [] buffer;		
		buffer = newBuffer;
		size = newSize;
	}
}

char& String::operator[](unsigned int index){
	return buffer[index];
}

bool String::operator==(const char* cp){	
	if (size != strlen(cp))
	     return false;
	 	
	else{
    		for(int i =0; i <= size && i!='\0'; i++){
			if (buffer[i] != cp[i])
				return false;
  		}
	}
  	return true;
}

bool String::operator==(String& cp){
	if (size != cp.size)
	     return false;
  	else{
    		for(int i =0; i < size; i++){
        		if (buffer[i] != cp.buffer[i])
				return false;
  		}
	}
  	return true;
}

void String::operator+=(const char* right){
	int newsize=size+strlen(right);
	char* newBuffer = new char[newsize];
	int i=0;
	while (i<=size){
		newBuffer[i]=buffer[i];
		i++;
	}
	for(;i<=newsize && right[i]!='\0'; i++){
		newBuffer[i]=right[i];
	}
	delete [] buffer;	
	buffer=newBuffer;
	size=newsize;
}

void String::operator=(const char* cp){
	buffer = 0;
	resize(strlen(cp), ' ');
	int i=0;
	while(cp[i]!='\0'){
		buffer[i]=cp[i];
		i++;
	}
}


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
// String_test.cpp

#include <iostream>
#include <cassert>
#include "String.h"

using namespace std;

int main()
{
   cout<<"Creating new String...\n";
   String s1; // s1 == ""
   cout<<"Asserting length...\n";
   assert(s1.length() == 0);

   cout<<"Creating new String with initialization...\n";
   String s2("hi");  // s2 == "hi"
   assert(s2.length() == 2);

   cout<<"Creating new String from Copy constructor...\n";
   String s3(s2);  // s3 == "hi"
   cout<<"Asserting...\n";
   assert(s3.length() == 2);
   assert(s3[0] == 'h');
   assert(s3[1] == 'i');
   
   cout<<"Testing assignment operator String:String...\n";
   s1 = s2;  // s1 == "hi"
   
   assert(s1 == s2);

   cout<<"Testing assignment operator String:char...\n";
   s3 = "bye";  // s3 == "bye"
   cout<<"Asserting length...\n";
   assert(s3.length() == 3);
   cout<<"Asserting buffer values...\n";
   assert(s3[0] == 'b');
   assert(s3[1] == 'y');
   assert(s3[2] == 'e');
   
   cout<<"Testing append operator...\n";
   s1 += "re";  // s1 == "hire"
   assert(s1 == "hire");

   cout<<"Testing append operator #2...\n";
   s1 += "d"; // s1 == "hired"
   assert(not (s1 == "hire"));

   cout << "SUCCESS" << endl;
}

Nothing looks immediately wrong, except for the fact that it looks like you've a memory leak on line 102 of the header. You set buffer to the null pointer, losing whatever data you had previously there.
String& operator=(String) is not overloaded and should be. Your problem occurs when you hit line 28 in your test program.
Pan, wouldn't that call the String(const char*) constructor? Or does that only apply for initializations?

EDIT: NVM mixed that one up.
Last edited on
Nothing looks immediately wrong, except for the fact that it looks like you've a memory leak on line 102 of the header. You set buffer to the null pointer, losing whatever data you had previously there.

That part was intentional. The data would have been erased anyway, and then replaced with whatever c-style string was to go in the buffer.

String& operator=(String) is not overloaded and should be. Your problem occurs when you hit line 28 in your test program.

That actually fixed the problem. I hadn't thought to overload the assignment operator for String, since I assumed that it'd follow the copy constructor code. Nevertheless, I shall make it a priority to overload for all instances in the future. Thanks for your help peeps. :)
Last edited on
Topic archived. No new replies allowed.