tags:

views:

2198

answers:

5

I have a C++ program on Linux that crashes after some time with the message:

*** glibc detected *** free(): invalid pointer: 0x41e0ce94 ***

Inside the program I make extensive use of containers. They have to store objects of a simple class.

EDIT 2009-4-17:

In the meantime it seems clear that the error has nothing to do with the simple class. The error still occurs if I change the containers to hold other datatypes. The problem must be somewhere else in my code, I'm trying to figure it out at the moment...

Thanks to everybody who contributed to my question so far, it was helpful and instructive anyway.

+3  A: 

At a guess, there is something wrong in your copy ctor, assignment op or destructor - you need to show the code for those.

Edit: Just noticed you don't have an assignment operator - assuming your copy constructor & destructor are OK, you need an assignment operator too, as the std:; containers will use it.

anon
Thanks for your answer. I tried it with an assignment operator now, but I would not help. Why would the default assignment operator not be sufficient? I basically used the destructor and copy constructor just for tracing purposes...
Chris
Post the real, full code, - ideally a simple example that crashes.
anon
The default copy constructor does a bitwise copy, so you would have 2 objects pointing to the same string. It then depends on your management of the string as to whether that is an issue.
Greg Domjan
@greg He has defined a copy ctor, so this point is moot.
anon
A: 

What is inside your destructor? Probably it does free of the cstring. And If it is the case then you share your cstring pointer over instances and each instance then frees the same pointer.

Mykola Golubyev
At the moment there is nothing inside the destructor, I ipmlemented it just for tracing purposes...
Chris
+4  A: 

Consider using a std::string to hold the string value instead of a raw char pointer. Then you won't have to worry about managing the string data in your assignment, copy, and destruction methods. Most likely your problem lies there.

Edit: There's no issue with the newer class you posted, and no problem with the first version if you're only using the char * to point to string constants. The problem lies elsewhere in the program or with the way you're using the class. You'll have to spend more time digging in the debugger and/or valgrind to track down the problem. I would figure out what is pointed to at the specified address and try determine why it's being freed twice.

karunski
Thanks. I will try that out. But most of the strings are __FILE__ string literals inserted by the preprocessor, and it has to be fast. I thought this will be the fastest implementation...
Chris
For your code to be correct you will be performing the exact same work as std::string. If nothing else std::string will be faster since it keeps track of the length of the string. If the C string ONLY points to string literals I suppose it doesn't matter.
karunski
Also, the class you posted doesn't contain any calls to free(), so it is not the source of your problem.
karunski
A: 

I have been fighting with a C/C++ application we are developing, and the first ideas that come to my mind are

  • A pointer has been modified and its pointing to an invalid possition (ptr++;) or something like that.
  • You have freed the object, but the pointer still holds the direction.

    A tool like Valgrind may help you to detect possible errors in the code. To install:

    sudo apt-get install valgrind

    And to use it:

    valgrind --tool=memcheck --leak-check=full ...

    It will report errors while the program is running, and it will give you also a report after the program ends. The only problem is what valgrind identifies as a possible problem may not be a real problem. But it is an starting point.

Daniel H.
Thanks for your answer. I already ran Valgrind, but I did not lead me to the problem's source... The program I'm working on is quite complex and has some other bugs, so it was a bit confusing. Maybe I will try it out again...
Chris
+1  A: 

It's most certainly a bad string value. Using std::string maybe help in this regard if it is a dangling pointer issue. Also ensure all the string initializations work as expected.

If I understand the class correctly, you assume that whatever memory resides at m_cstring won't be deallocated for the lifetime of the class. Which in your case also means for the lifetime of the containers. Check your scopes.

Another problem you may be encountering is if your Destructor is deleting the cstring then using a default value in the constructor is a really bad idea as you will be trying to deallocate a statically allocated cstring.

It is possible in C++ to define a function that is supposed to return a string, but doesn't return anything and you wind up with a bad string (Typically the compiler will catch the 'Reached end of non-void function', but not always).

Ditto on using valgrind.

As an addendum after reading various comments, there's always the possibility that a memory error somewhere else in the program corrupted one of the strings.

EDIT 4-16

At this point I would verify the values of the object are well formed on construct/destruct. (try printing them?) If everything looks good, you may have to look elsewhere in your code for the error.

TK
TK, thanks for the comment. What exactly do you mean with well formed? Especially when working without m_string, there cannot be a lot of errors... It looks to me like something suddenly gets mixed up in the containers. Maybe you are right and it's a different part of the program. Sigh.
Chris
My usual glibc/segfaults are from passing a not null terminated str, an uninitialized pointer, or a bad free somewhere else in the program corrupting my string. You're still having the issue without the string member, so that's a head scratcher. Other usual case is misuse of smart ptrs. Valgrind?:-/
TK