Re: malloc() fail
The Doctor wrote:
Hey people,
I have a really weird problem.
I am developing a string class, just for fun. I am also writing an
application, which uses the string class, and uses a lot of them. But,
after about thirty String string = new String("blahblahblah"), I get the
following error:
new String(""); returns a pointer, but String string; is not a pointer,
so you cannot assign one to the other.
Anyway, why do you new the String? Whats wrong with this:
String str("blahblahblah");
You seem to have a Java or .NET background.
*** glibc detected *** ./myapp: malloc(): memory corruption (fast):
You corrupted some memory, perhaps by deleting memory twice or by
writing over the bound of an array.
The code where the app crashes:
String::String(const char* other)
{
/*
allocate space for the actual string data, the Data structure
contains an int, which contains the length of the string, and a
pointer to a short array.
*/
d = (Data*)malloc(sizeof(Data));
Any reason the Data structure is not part of the String class itself?
class String
{
// constructors and member functions...
protected:
size_t length;
short* data;
};
/*
Allocate new data space, this is where the application crashes
*/
d->data = (short*)malloc(sizeof(short));
malloc is a C function. C has a rule of thumb: NEVER cast the result of
malloc. Why? Because it masks bugs in your code. In C, you don't need
the cast.
But in C++, we can't use malloc without a cast, what to do? Don't use
malloc, use new[]!
With the above data structure in the class, you would do:
length = 0; // let length be the real string length
data = new short[length + 1]; // +1 for terminating 0
data[length] = '\0';
Don't forget to delete[] the data in the destructor!
Another common mistake is to forget the Rule of Three:
Whenever you have to define a destructor, a copy constructor or an copy
assignment operator, you most likely have to define the other two.
Did you define a copy constructor and an assignment operator?
/*
Set the fist byte of the string to zero, the terminating 0 byte.
*/
d->size = 1;
memset(d->data, 0, sizeof(short));
memset should rarely be used in C++, too.
/*
And append the other char array, with the append function.
*/
append(other);
}
I totally don't get my mistake. Does anyone of you knows what I am doing
wrong?
You posted too less code.
You didn't use the proper C++ operations.
There are also std::string, std::wstring and std::vector, which would
take care of the memory issues.
--
Thomas