malloc() fail

T

The Doctor

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:

*** glibc detected *** ./myapp: malloc(): memory corruption (fast):
0x080641f8 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7bea962]
/lib/tls/i686/cmov/libc.so.6(__libc_malloc+0x8d)[0xb7bebcad]
/usr/lib/libLCore.so(_ZN7StringC1EPKc+0x4b)[0xb7eeafff]
../ka[0x804d3e4]
../ka[0x804b72a]
../ka(__gxx_personality_v0+0x3f4)[0x804b244]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7b94450]

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));

/*
Allocate new data space, this is where the application crashes
*/
d->data = (short*)malloc(sizeof(short));

/*
Set the fist byte of the string to zero, the terminating 0 byte.
*/
d->size = 1;
memset(d->data, 0, sizeof(short));

/*
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?
 
J

Juha Nieminen

The said:
I totally don't get my mistake. Does anyone of you knows what I am doing
wrong?

Without seeing the entire code it may be difficult to say. There may
be an error in your memory handling, string resizing, or anything.
 
E

Erik Wikström

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:

*** glibc detected *** ./myapp: malloc(): memory corruption (fast):
0x080641f8 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7bea962]
/lib/tls/i686/cmov/libc.so.6(__libc_malloc+0x8d)[0xb7bebcad]
/usr/lib/libLCore.so(_ZN7StringC1EPKc+0x4b)[0xb7eeafff]
./ka[0x804d3e4]
./ka[0x804b72a]
./ka(__gxx_personality_v0+0x3f4)[0x804b244]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7b94450]

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));

/*
Allocate new data space, this is where the application crashes
*/
d->data = (short*)malloc(sizeof(short));

I can't see anything wrong with the code so far, you need to post (at
least) the definition of Data (please see the FAQ on how to post a
question).

A question though, why use malloc and not new?
 
T

The Doctor

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:

*** glibc detected *** ./myapp: malloc(): memory corruption (fast):
0x080641f8 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7bea962]
/lib/tls/i686/cmov/libc.so.6(__libc_malloc+0x8d)[0xb7bebcad]
/usr/lib/libLCore.so(_ZN7StringC1EPKc+0x4b)[0xb7eeafff] ./ka[0x804d3e4]
./ka[0x804b72a]
./ka(__gxx_personality_v0+0x3f4)[0x804b244]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7b94450]

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));

/*
Allocate new data space, this is where the application crashes */
d->data = (short*)malloc(sizeof(short));

I can't see anything wrong with the code so far, you need to post (at
least) the definition of Data (please see the FAQ on how to post a
question).

A question though, why use malloc and not new?

Data:
struct Data
{
int size;
short* data
};


Would new and delete[] have prevented this then?

It is impossible to post the whole code, since it is huge.
 
T

Thomas J. Gritzan

The said:
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.
 
R

Rolf Magnus

It means you have a memory error, like e.g. writing past the end of an array
or trying to free a block of memory you already have freed, or calling free
with an address you didn't get from malloc.
0x080641f8 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7bea962]
/lib/tls/i686/cmov/libc.so.6(__libc_malloc+0x8d)[0xb7bebcad]
/usr/lib/libLCore.so(_ZN7StringC1EPKc+0x4b)[0xb7eeafff] ./ka[0x804d3e4]
./ka[0x804b72a]
./ka(__gxx_personality_v0+0x3f4)[0x804b244]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7b94450]

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));

/*
Allocate new data space, this is where the application crashes */
d->data = (short*)malloc(sizeof(short));

A typical problem of this kind of bug is that the program often doesn't
crash at the place where the actual error is. It's likely that the last
memory allocation or deallocation you did before this one broke the memory
manager's internal data. If you happen to be using linux/x86, you can try
using valgrind. It's a memory debugger that can tell you in which line of
your code the real error is.
Data:
struct Data
{
int size;
short* data
};

That doesn't really help much.
Would new and delete[] have prevented this then?

Probably not.
It is impossible to post the whole code, since it is huge.

You sould rather reduce your program to the smallest complete program that
still contains the error. Chances are that you will find the error in the
process. If not, you can post that reduced version of the program.
 
J

James Kanze

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:
*** glibc detected *** ./myapp: malloc(): memory corruption (fast):
0x080641f8 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7bea962]
/lib/tls/i686/cmov/libc.so.6(__libc_malloc+0x8d)[0xb7bebcad]
/usr/lib/libLCore.so(_ZN7StringC1EPKc+0x4b)[0xb7eeafff]
./ka[0x804d3e4]
./ka[0x804b72a]
./ka(__gxx_personality_v0+0x3f4)[0x804b244]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7b94450]
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));

Why not "new Data", instead of malloc? Or even "new Data()",
ensuring zero initialization.
/*
Allocate new data space, this is where the application crashes
*/
d->data = (short*)malloc(sizeof(short));

This looks very strange. Why not just declare a short in Data,
rather than a pointer to it? (The pointer might make sense if
you were pointing to more than one, but even then, unless the
goal is to learn how to do low level memory management,
std::vector would be preferrable.)
/*
Set the fist byte of the string to zero, the terminating 0 byte.
*/
d->size = 1;
memset(d->data, 0, sizeof(short));

Why memset? Why not simply "*d->data = 0 ;"?
/*
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?

Probably a lot of things; most of the code above looks funny.
But without seeing more (e.g. the append function, the structure
of Data, and above all, the class invariants), it's impossible
to say.

Note too that a memory corruption error in malloc will be
detected after (and often long after) the corruption actually
took place, and often in a completely different component.
 
J

James Kanze

The Doctor wrote:

[...]
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[]!

If he's allocating sizeof(short), and assigning it to a short*
(which seems to be the case), it's new he should use, and not
new[].

Thinking about it, I wonder if he isn't trying to use the dirty
struct hack. And that what he really wants to do is malloc(
sizeof( short ) + numberOfCharactersInString ).
 
T

Thomas J. Gritzan

James said:
The Doctor wrote:
[...]
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[]!

If he's allocating sizeof(short), and assigning it to a short*
(which seems to be the case), it's new he should use, and not
new[].

If he's allocating only a single sizeof(short) and assigning to a
short*, he shouldn't use dynamic allocation.

My guess is that its the empty string (zero terminator only). The data
structure is a pimpl (for whatever reason) and the data member of this
struct is a wide string pointer. In that case, he will allocate
sizeof(short) * (length+1) memory. The +1 is for the terminating zero:

The said:
/*
Set the fist byte of the string to zero, the terminating 0 byte.
*/
d->size = 1;
memset(d->data, 0, sizeof(short));

James said:
Thinking about it, I wonder if he isn't trying to use the dirty
struct hack. And that what he really wants to do is malloc(
sizeof( short ) + numberOfCharactersInString ).

Another possible interpretation.
 
G

Gianni Mariani

The said:
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:

*** glibc detected *** ./myapp: malloc(): memory corruption (fast):
0x080641f8 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7bea962]
/lib/tls/i686/cmov/libc.so.6(__libc_malloc+0x8d)[0xb7bebcad]
/usr/lib/libLCore.so(_ZN7StringC1EPKc+0x4b)[0xb7eeafff]
./ka[0x804d3e4]
./ka[0x804b72a]
./ka(__gxx_personality_v0+0x3f4)[0x804b244]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7b94450]

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));

/*
Allocate new data space, this is where the application crashes
*/
d->data = (short*)malloc(sizeof(short));

/*
Set the fist byte of the string to zero, the terminating 0 byte.
*/
d->size = 1;
memset(d->data, 0, sizeof(short));

/*
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?


Show us what String::~String looks like..

BTW - what's wrong with :

typedef std::basic_string<short> String;
String foo( other, other + strlen(other) );

??? i.e. get rid of your own String class completely?
 
J

James Kanze

Gianni Mariani wrote: [...]
BTW - what's wrong with :
typedef std::basic_string<short> String;
1) It's not as much fun. Fun was the OP's stated goal.
2) The standard doesn't define char_traits specializations for anything
other than char and wchar_t. char_traits<short> could mean different
things with different standard library implementations, and so could
basic_string<short>.

For that matter, the standard doesn't require a generic
implementation char_traits at all, in which case,
basic_string<short> won't even compile. (Most compilers do
provide one, but I've heard actual complaints that the semantics
it defines are not the same, at least for unsigned integral
types, with g++ and VC++.)

When all is said and done, all making std::basic_string a
template bought us was to make it easier for the standards
committee to add new string types down the road, e.g.
std::basic_string< char16_t > (which will be present in the next
version of the standard).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,152
Members
46,697
Latest member
AugustNabo

Latest Threads

Top