new sets up incorrect data fields

This is a discussion on new sets up incorrect data fields within the C++ Programming forums, part of the General Programming Boards category; I have this class, which is derived from std::string. In a certain piece of code, where I allocate an array ...

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    250

    new sets up incorrect data fields

    I have this class, which is derived from std::string. In a certain piece of code, where I allocate an array of these derived classes on the heap, the std::string internal data pointer (_M_p) is not setup correctly for some reason (in this particular case it point to address 0x10, which is obviously out of bounds), so that on subsequent assignment to my array, I get segfaults:

    Code:
    m_derivedArray = new Derived[x]; // <-- internal data pointer of std::string is setup incorrectly for some reason
    Derived[i] = ""; // <-- segfault
    where m_derivedArray, is a member of some class. And yes, i is within the range 0 <= i < x, I checked that.

    Unfortunately I am not able to reproduce the problem in a short program, the complete code is too complicated too post here (big project), and in other instances of the code, the allocation seems to be working fine.

    Does anyone have any hints on how to debug this problem? As the problem _seems_ to occur in new I am clueless. I am working on a linux platform and compiling with g++ if that's any help.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,274
    I have this class, which is derived from std::string.
    std::string is not designed to be a base class (in particular, it does not have a virtual destructor) so you should not derive from it, at least not with public inheritance. Use composition instead.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    250
    Quote Originally Posted by laserlight View Post
    std::string is not designed to be a base class (in particular, it does not have a virtual destructor) so you should not derive from it, at least not with public inheritance. Use composition instead.
    Okay, noted. But still, this does not explain why the class is setup incorrectly, or does it?

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,344
    Can you post a simple but complete and compilable example that demonstrates the problem? There might be an error somewhere else in the code that should be fixed even when you change to composition.

  5. #5
    Registered User
    Join Date
    Oct 2006
    Posts
    250
    Quote Originally Posted by Daved View Post
    Can you post a simple but complete and compilable example that demonstrates the problem? There might be an error somewhere else in the code that should be fixed even when you change to composition.
    Quote Originally Posted by MWAAAHAAA
    Unfortunately I am not able to reproduce the problem in a short program
    Thanks you for taking the time to read my post thoroughly.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,274
    But still, this does not explain why the class is setup incorrectly, or does it?
    I suspect it does not, and Daved seems to think the same, but without an example to work from, this is all just guess and check, so I suggest that you implement composition first and see if your problem is resolved. If it is not resolved, well, at least you are a step closer to the correct solution.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,344
    >> Thanks you for taking the time to read my post thoroughly.
    Sorry about that, I did fail to read it thoroughly. Good luck with your problem.

  8. #8
    Registered User
    Join Date
    Oct 2006
    Posts
    250
    Quote Originally Posted by laserlight View Post
    I suggest that you implement composition first and see if your problem is resolved.
    I implemented composition instead of inheriting, but the result is the same, directly after the call to new[], the internal data pointer of the now embedded std::string object is setup incorrectly starting with the second element of the array (again the same value 0x10, instead of a proper pointer).

    The thing I do not understand is that this happens immediately after the new[] call. It is not that I first execute some other code that could possibly corrupt my array, new[] actually gives me an array with corrupted objects.

    I really have no clue as to how to approach this problem.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,274
    hmm... I cannot see how this problem could have come about.

    I think you really have to try and find the smallest and simplest program that demonstrates the problem. If this means starting back from scratch, so be it, or you will always have this bug.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,344
    >> I really have no clue as to how to approach this problem.
    If you can't reproduce it in a smaller example, try commenting out code in your larger example until it no longer happens. Start with the things you think obviously won't affect it. Try commenting out the other members and base classes of your class. Perhaps you can post your class definition and constructor definition to see if anybody can spot a problem. The call to new probably isn't doing anything wrong, but the constructor for the class and/or other members might be.

  11. #11
    Registered User
    Join Date
    Oct 2006
    Posts
    250
    Quote Originally Posted by Daved View Post
    but the constructor for the class and/or other members might be.
    That's just it, I only call the default constructor, which does absolutely nothing, except of course that the std::string default constructor is also called because of inheritance, which should properly set up its own private data members, but for some reason doesn't.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MWAAAHAAA View Post
    That's just it, I only call the default constructor, which does absolutely nothing, except of course that the std::string default constructor is also called because of inheritance, which should properly set up its own private data members, but for some reason doesn't.
    More than likely, there is SOMETHING that overwrites this data - and I think you have been given sound advice on how to find the source of the problem - unfortunately, there's only two ways you can find this sort of problem :
    1. Narrow it down until there is nearly nothing left of your code, and then it's usually obvious.
    2. Set up a debugger to trigger on writing to the relevant data area. This is often quite useful for finding bugs of this sort [it is quite often the case where code is doing "stupid" array operations and failing to stop at the given limit of an array, overwriting some other data, and causing a problem like this].
    [Ok, a third way is to "guess your way to it", but it's usually not a very quick way].

    Finally, if you are using a common compiler with a common implementation of std::string, then its constructor (whichever version of it you are using) is almost certainly correct. If you are using an unusual/rarely used implementation of string library, it is of course possible that it the implementation is broken in trivial ways.


    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,344
    Are there any other non-POD members? Those will be constructed as well, and could potentially be corrupting the memory of the string.

    Did you #include<string> properly? Rebuild your full project recently? It's a long shot, but I've seen similar errors with bad builds or confused compilers.

    Also, are you sure the string is not constructed properly? I've seen the debugger's version of the string class and it looks like it's not right but it is in fact valid. The crash might be being caused by something completely different. For example, perhaps for small or empty strings it doesn't use the internal buffer until you assign a string to it.

    Finally, what other code does dynamic memory allocation before the crash? Could access to that be corrupting the memory.

  14. #14
    Registered User
    Join Date
    Oct 2006
    Posts
    250
    Quote Originally Posted by Daved View Post
    Are there any other non-POD members? Those will be constructed as well, and could potentially be corrupting the memory of the string.
    Nope, no data members at all, just function definitions.

    [
    Quote Originally Posted by Daved View Post
    Did you #include<string> properly? Rebuild your full project recently? It's a long shot, but I've seen similar errors with bad builds or confused compilers.
    Yep. Rebuilt it completely, after a make distclean.

    Quote Originally Posted by Daved View Post
    Also, are you sure the string is not constructed properly? I've seen the debugger's version of the string class and it looks like it's not right but it is in fact valid.
    The string is definitely not constructed properly. It does not look like a debugger screwup though, e.g. std::string::npos is initialized to the proper value of -1, whereas the internal data pointer is given an invalid pointer, i.e. it is neither 0, nor does it point to a valid location.

    Quote Originally Posted by Daved View Post
    The crash might be being caused by something completely different. For example, perhaps for small or empty strings it doesn't use the internal buffer until you assign a string to it.
    I am quite positive that the crash is caused by something different, just what is a mystery to me. My code actually starts crashing as soon as I assign a string to the string class. At that point I noticed that the internal data pointer had this strange value (0x10), and traced this back to the new[] call. I am quite sure that the std::string implementation and the new[] implementation are bug free, since I am using an up to date version of g++ and libstdc++. Besides, new[] and std::string, or the string class in question, do not give me any error in other places, they seem to work fine, except in this particular instance.

    Quote Originally Posted by Daved View Post
    Finally, what other code does dynamic memory allocation before the crash? Could access to that be corrupting the memory.
    As already mentioned, as soon as the new[] call returns, the internal data pointer is screwed up. No other code was executed. What I did was basically set a breakpoint on the new[] call, step over it, and took a look at the contents of my newly allocated array.

    Quote Originally Posted by matsp
    1. Narrow it down until there is nearly nothing left of your code, and then it's usually obvious.
    In case of any other bug, that's just what I do. But how would I go about narrowing down a single new[] statement? Because that's what I currently narrowed it down to.

    Quote Originally Posted by matsp
    2. Set up a debugger to trigger on writing to the relevant data area
    That's a nice idea, except that I don't actually get the relevant data area until after the new[] call, at which point the data is already corrupted.

    Quote Originally Posted by matsp
    Finally, if you are using a common compiler with a common implementation of std::string, then its constructor (whichever version of it you are using) is almost certainly correct.
    I do not think the problem is with either the std::string constructor, or the new[] operator, since I am using a standard GCC build. Nothing modified or adjusted.

    In short I am rather clueless. I'll try rearranging some code, inserting some similar/identical new[] statements, see what happens. Any more advise is of course welcome.

  15. #15
    Registered User
    Join Date
    Jan 2005
    Posts
    7,344
    You can't keep insisting that it all happens in the new[] call. There's a very good chance that it doesn't. Open your mind to other possibilities and check them all out even if they seem impossible.

    When you step over the new[] call, can you step into the constructors? What does a normal _M_p pointer point to when a string is constructed correctly (e.g. in your small sample program that does not reproduce the error)?

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 48
    Last Post: 09-26-2008, 04:45 AM
  2. Reading a file with Courier New characters
    By Noam in forum C Programming
    Replies: 3
    Last Post: 07-07-2006, 10:29 AM
  3. All u wanted to know about data types&more
    By SAMSAM in forum Windows Programming
    Replies: 6
    Last Post: 03-11-2003, 03:22 PM
  4. C Programming Question
    By TK in forum A Brief History of Cprogramming.com
    Replies: 13
    Last Post: 07-04-2002, 08:11 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21