I am trying to write a basic string class for practice, and I am struggling with the reserve() function to increase my char array's memory allocation.
This is the error message I get:
free(): double free detected in tcache 2
This is my approach:
void string::reserve(size_t n)
{
if (n <= space+1) return; // never decrease allocation
char *p = new char[n+1]; // allocate new space
for (int i=0; i<sz; ++i) p[i]=pChars[i]; // copy old elements
//strcpy(p, pChars); // didn't work either
p[n] = '\0';
delete[] pChars; // deallocate old space
pChars = p;
space = n+1;
}
I will also share a picture of my header file below:
Here is the entire code:
#include "String.h"
namespace String
{
string::string(): sz(0), pChars(nullptr), space(0) {}
string::string(const char* s): sz(strlen(s)), pChars(new char[strlen(s)+1]), space(sz+1) ///Constructor using a null-terminated C String
{
//for (int i = 0; s[i] != '\0'; i++) pChars[i] = s[i];
strcpy(pChars,s);
pChars[strlen(s)] = '\0';
}
string::string(const string& s): sz(s.sz), pChars(new char[s.sz]), space(s.sz) ///copy constructor
{
for (size_t i = 0 ; i<s.sz; i++) pChars[i] = s.pChars[i];
pChars[s.sz] = '\0';
}
string& string::operator=(const string& s) ///copy assignment
{
if (this==&s) return *this; // self-assignment, no work needed
if (s.sz<=space)
{ // enough space, no need for new allocation
for (size_t i = 0; i<s.sz; ++i) pChars[i] = s.pChars[i]; // copy elements
sz = s.sz;
return *this;
}
char *p = new char [s.sz]; // copy and swap
for (size_t i = 0; i<s.sz; ++i) p[i] = s.pChars[i];
delete[] pChars;
sz = s.sz;
space = s.sz;
pChars = p;
return *this;
}
string& string:: operator=(const char* s) ///copy assignment using a null-terminated C String
{
char *p = new char[strlen(s)+1];
for(size_t i = 0; s[i] != '\0'; i++) p[i] = s[i];
p[sz] = '\0';
delete [] pChars;
sz = strlen(s);
space = sz;
strcpy(pChars, p);
return *this;
}
///string(string&& s); ///move constructor, not needed (compiler copy elision)
string& string:: operator=(string&& s) ///move assignment
{
delete[] pChars; // deallocate old space
pChars = s.pChars; // copy a's elem and sz
sz = s.sz;
space = s.space;
s.pChars = nullptr; // make a the empty vector
s.sz = 0;
cout << "Move" << endl;
return *this;
}
string::~string()
{
delete [] pChars;
}
char& string:: operator[](size_t pos) {return pChars[pos];} ///set operator
const char& string:: operator[](size_t pos) const {return pChars[pos];} ///get operator
void string::reserve(size_t n)
{
if (n <= space+1) return; // never decrease allocation
char *p = new char[n+1]; // allocate new space
for (int i=0; i<sz; ++i) p[i]=pChars[i]; // copy old elements
//strcpy(p, pChars);
p[sz] = '\0';
delete[] pChars; // deallocate old space
pChars = p;
space = n+1;
}
void string:: push_back(const char c) ///push char c to the end
{
if (sz==0) // no space: grab some
reserve(8);
else if (sz==space) // no more free space: get more space
reserve(2*space);
pChars[sz] = c; // add d at end
++sz; // and increase the size (sz is the number of elements)
}
bool operator==(const string& lhs, const string& rhs) ///check equality (same size, all chars the same)
{
if (lhs.size() != rhs.size()) return false;
else
{
for (size_t i = 0; i<lhs.size(); i++)
{
if (lhs[i] != rhs[i]) return false;
}
}
return true;
}
bool operator==(const string& lhs, const char* rhs) ///equality with null terminated C string
{
if(lhs.size() == strlen(rhs))
{
for (size_t i = 0; i< lhs.size(); i++)
{
if(lhs[i] == rhs[i]) return true;
}
}
return false;
}
bool operator>(const string& lhs, const string& rhs) ///greater than operator, true if lhs > rhs
{
}
string operator+(const string& lhs, const string& rhs) ///concatenate two MyStrings, return the result
{
}
ostream& operator<<(ostream& os, const string& s)
{
for (size_t i = 0; i<s.size(); i++)
{
os << s[i];
}
return os;
}
istream& operator>>(istream& is, string& s)
{
char c;
while(is.get(c))
{
if (c!=' ') s.push_back(c);
}
return is;
}
}

p[n] = '\0';instead ofp[sz] = '\0';? This might be a reason whystrcpydid not work.std::vectorin the custom string class.