• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Rép : XCode, cin and string (C++) => troubles :s
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Rép : XCode, cin and string (C++) => troubles :s


  • Subject: Re: Rép : XCode, cin and string (C++) => troubles :s
  • From: Andreas Grosam <email@hidden>
  • Date: Sun, 14 Feb 2010 20:04:02 +0100

Well, I was curious and did some more investigation.

Firstly, I was wrong that the preprocessor symbols _GLIBCXX_DEBUG, and _GLIBCXX_DEBUG_PEDANTIC can not be set in Xcode for client programs. In fact, these symbols affect only the headers included - but do not have any dependency on library code. So, these switches are not private, and according the C++ Lib documentation these are means for debugging client applications.

Consequently, the Xcode project template is correct. As a measurement for testing, I put them back.



But, if these switches are set, this strange error occurs. So, what is happening? I looked even deeper into the details, and it turned out that it became pretty weird:

Your main program looks like this:

int main (int argc, char * const argv[]) {
    string input = "";
    getline(cin, input);
    std::cout << "input: " << input << std::endl;
    return 0;
}

the error:
test(81379) malloc: *** error for object 0x1000062a0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Program received signal:  “SIGABRT”.


The stack when the pointer is attempted to be freed, is as follows:

#0	0x7fff80d5bfe6 in __kill
#1	0x7fff80dfce32 in abort
#2	0x7fff80d14155 in free
#3	0x7fff86ce71e8 in std::string::reserve
#4	0x7fff86ce7243 in std::string::push_back
#5	0x7fff86cd02b5 in std::getline<char, std::char_traits<char>, std::allocator<char> >
#6	0x100002919 in std::getline<char, std::char_traits<char>, std::allocator<char> > at basic_string.h:2451
#7	0x1000013de in main at main.cpp:73


It should be noted, that the C++ library functions are almost all template functions, and many are inlined. All these functions will be "included", then instantiated, and then form a single translation unit with the main program. You can get a view how this looks like, when calling the preprocessor on main.cpp

And, it should also be noted, that Xcode is not able to debug template functions  :(


As a first attempt to figure out what's happening and where, I simulated the getline function at this point where the error occurs in the original function according the stack:

int main (int argc, char * const argv[]) {
    string input = "";
    input += 'c';
    return 0;
}
---> no error, strange because this would call push_back(), then reserve() - but here is no error.

int main (int argc, char * const argv[]) {
    string input = "";
    input.reserve(10);
    return 0;
}
---> no error, strange - same as above.


Hm, maybe something strange is happening in getline?

Debugging was impossible, this is a template function, and gdb cannot find sources. So, I decided make a copy of the getline function, and use and debug this one. Just not as a template function, but exactly equal the function the compiler would instantiate. I gave it a different name in order to not conflict with the template function, which would always selected before a normal function. It looks as follows, which is essentially verbatim copy of the template function, but instantiated "by hand":

std::istream&
get(std::istream& __in, std::string& __str, char __delim)
{
    typedef istream __istream_type;
    typedef  __istream_type::int_type __int_type;
    typedef  __istream_type::__streambuf_type __streambuf_type;
    typedef  __istream_type::__ctype_type __ctype_type;
    typedef std::string __string_type;
    typedef  __string_type::size_type __size_type;

    __size_type __extracted = 0;
    const __size_type __n = __str.max_size();
    ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    __istream_type::sentry __cerb(__in, true);
    if (__cerb)
    {
        try
        {
            __str.erase();
            const __int_type __idelim = std::char_traits<char>::to_int_type(__delim);
            const __int_type __eof = std::char_traits<char>::eof();
            __streambuf_type* __sb = __in.rdbuf();
            __int_type __c = __sb->sgetc();

            while (__extracted < __n
                   && !std::char_traits<char>::eq_int_type(__c, __eof)
                   && !std::char_traits<char>::eq_int_type(__c, __idelim))
            {
                __str += std::char_traits<char>::to_char_type(__c);
                ++__extracted;
                __c = __sb->snextc();
            }

            if (std::char_traits<char>::eq_int_type(__c, __eof))
                __err |= ios_base::eofbit;
            else if (std::char_traits<char>::eq_int_type(__c, __idelim))
            {
                ++__extracted;
                __sb->sbumpc();
            }
            else
                __err |= ios_base::failbit;
        }
        catch(...)
        {
            __in._M_setstate(ios_base::badbit);
        }
    }
    if (!__extracted)
        __err |= ios_base::failbit;
    if (__err)
        __in.setstate(__err);
    return __in;
}



So, then I ran the supposedly identical program again:

int main (int argc, char * const argv[]) {
    string input = "";
    char delimiter = cin.widen('\n');
    get(cin, input, delimiter);
    std::cout << "input: " << input << std::endl;
    return 0;
}


And?

NO error!!  ??

Yes, no error. In *theory* the programs MUST not differ. So, there should be the same error - but no.
The original uses a template function, the second uses a normal function, which is identical. So, if I am right, it seems the compiler does some weird stuff when instantiating the template function.

Please note, this program does not depend on libraries, it is for the most part, headers only - especially where it fails. The real difference turns out to be the instantiation of the template function, which is a compiler thingy.


Regards

Andreas





 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: Rép : XCode, cin and string (C++) => troubles :s
      • From: Andreas Grosam <email@hidden>
References: 
 >Rép : XCode, cin and string (C++) => troubles :s (From: Arnaud Schoofs <email@hidden>)
 >Re: Rép : XCode, cin and string (C++) => troubles :s (From: Andreas Grosam <email@hidden>)

  • Prev by Date: Re: Upon break, debugger not showing correct line in source
  • Next by Date: Re: Upon break, debugger not showing correct line in source
  • Previous by thread: Re: Rép : XCode, cin and string (C++) => troubles :s
  • Next by thread: Re: Rép : XCode, cin and string (C++) => troubles :s
  • Index(es):
    • Date
    • Thread