Reputation: 35
I'm trying to overloading the operator new of my class, I wanna allocate space for the objects' attributes and for a vector of chars that isn't defined in the class.
But when I instance an new object, the chars of previously object are changing. Am I doing something wrong?
class StringData
{
public:
friend class String;
int refCount;
int len;
int maxLen;
~StringData()
{
}
StringData()
{
maxLen = 1000;
len = 0;
refCount = 1;
}
StringData(const char * string)
{
maxLen = 1000;
char * data = buffer();
len = 0;
while (string[len] != '\0' && len < (maxLen - 1))
{
data[len] = string[len];
len++;
}
data[len] = '\0';
refCount = 1;
}
char* buffer()
{
return reinterpret_cast<char*>(this + 12);
}
public:
void* operator new(size_t size, int maxLen)
{
return ::operator new(size + round4(maxLen + 1));
}
static int round4(int len)
{
return ((((int) (len / 4)) + 1) * 4);
}
void operator delete(void* obj)
{
::operator delete(obj);
}
void operator delete(void* obj, int size) throw ()
{
::operator delete(obj);
}
};
I use this in other class:
class String{
public:
StringData * data;
String(StringData * data){
this->data = data;
}
public:
String(const char*);
String(const String&);
~String();
String& operator =(const String);
String& operator =(const char *);
int length() const;
bool operator ==(const String&) const;
int compare(const String&) const;
bool operator ==(const char*) const;
int compare(const char*) const;
String& operator +(const String&) const;
String operator +(const char*) const;
String operator +=(const String&);
String operator +=(const char*);
String toLower();
String toUpper();
char operator [ ](int) const;
char& operator [ ](int);
void print() const;
};
String::String(const char * string){
int stringLen = 0;
while (string[stringLen] != '\0')
stringLen++;
data = new (stringLen + 1) StringData(string);
}
String::String(const String& string){
data = string.data;
string.data->refCount++;
}
String::~String(){
this->data->refCount--;
if (this->data->refCount == 0)
delete data;
}
String& String::operator=(const String string){
data->refCount--;
if (this->data->refCount == 0)
delete data;
data = string.data;
string.data->refCount++;
return *this;
}
void String::print() const{
printf("%s\n", data->buffer());
}
And my main function is:
int main(){
String *a = new String("boisahzashdacaraverdeepretaeazuleamarelaecinzaevermelha");
a->print();
String * s = new String("freestepehnoisquevoaashashashhasshashhasssasassadasd");
String * b = new String("kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
a->print();
s->print();
return 0;
}
When I execute, the strings are broken:
boisahzashdacaraverdeepretaeazuleamarelaecinzaevermelha
boisahzashdacaraverd
freestepehnoisquevoa
Upvotes: 2
Views: 304
Reputation: 129454
This is not a great idea:
return reinterpret_cast<char*>(this + 12);
Not only does it fail if you ever add/remove some member functions [or make a virtual function], but it's also dependent on the size of int
.
Use
return reinterpret_cast<char*>(this) + sizeof(*this);
[Note newplacement of the end of reinterpret_cast<>()!!]
The first version skips 12 * sizeof(*this)
forwards, rather than 12
bytes.
[Of course, on my machine, when I used the 4* multiplier of maxLen, it actually works - it only began failing when I removed that]
This can be simplified:
((((int) (len / 4)) + 1) * 4);
Is this supposed to be 4 times larger than maxlen:
(4 * maxLen)
to:
4 * (len / 4 + 1);
I will be back with edits to this answer once I know the answer to the comment about how it is being tested.
Upvotes: 1