EXC_BAD_ACCESS when creating istringstream

It got me. I am trying to write a templated function to convert a string to different data types. It should be able to compile on twelve different platforms, so using boost is not a convenient option. I took a step back to just a function that converts a string to a long one. Here's the simplest version of what she looks like ...

long string_to_long(string &str) {
    istringstream stream(str);
    long n;
    stream >> n;
    return n;
}

      

With both the templated function and this more specific function, I get poor memory access as soon as I create the istringstream. If I initialize istringstream without passing the str variable to it, it still crashes. My stack trace looks like this ...

(gdb) thread apply all bt

Thread 1 (core thread 0):
#0  0x00007fff89ba35b6 in pthread_threadid_np ()
#1  0x00007fff89ba10b9 in pthread_mutex_lock ()
#2  0x00007fff8ab1baf5 in __gnu_cxx::__mutex::lock ()
#3  0x00007fff8ab22903 in std::locale::locale ()
#4  0x00007fff8ab2c582 in std::basic_ios<char, std::char_traits<char> >::basic_ios ()
#5  0x00007fff8ab44d2e in std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >::basic_istringstream ()
#6  0x000000010e0b53e3 in my_file::string_to_long (this=0x7fff6dca0380, str=@0x7fff6dc9ff20) at my_file.cpp:46
#7  0x000000010e0b72e8 in my_file::add_prop (this=0x7fff6dca0380, props=0x7f9013c01510, prop_node=0x7fff6dca16c0) at my_file.cpp:392
#8  0x000000010e0b8864 in my_file::run_test_section (this=0x7fff6dca0380, tests_node=0x7fff6dca0428, section_name=@0x7fff6dcb0500, sibling_name=@0x7fff6dcb04f0) at my_file.cpp:135
#9  0x000000010e0b2b3b in main (argc=3, argv=0x7fff6dcb0828) at main.cpp:39
(gdb)

      

I tried adding string_to_long () to an empty C ++ project that only has a main function. It works great in this scenario. In an application I use this feature, adding calls to it at specific locations will randomly work for one call and fail on the next. I used this call to test it and it will be successful every time after a while.

string num = "1234";
long long_val = string_to_long(num);

      

I have all the ideas. It seems to have something to do with compilation, linking, or stack issue.

Perhaps this file matters ...

#include <fstream>
#include <sstream>
#include "myfile.h"

      

... and myfile.h (name not explicitly specified) includes ...

#include <map>
#include <string>
#include "rapidxml/rapidxml.hpp"

      

Update

I still don't know what is causing this. I spent a few days training. I am working on this project on Mac OS Lion in Netbeans. When I compile and run it on Linux and Solaris using the same makefiles that netbeans generates, it's fine.

As for the istringstream issue, I pulled istringstream create from the function call and made it a private member variable. I'm not crazy about having more member variables than absolutely necessary, but in this case, this is a workaround. It will also reduce object creation.

The crash problem still causes an ugly head when I use istringstream to convert int / long / short and then use the same stream to convert float or double. Here is the code I ended up with. I will post an update if I find out exactly what the problem is with Mac OS.

Here is the code I ended up with. I hate not knowing what is causing this.

template<class T>T string_to(const string &str) 
{
    stream.str(str);
    T t;
    stream >> t;
    if (stream.fail()) {
        runtime_error("Conversion failed");
    }
    stream.clear();
    return t;
}

      

+3


source to share


1 answer


Given that you have thread handling on the crash stack, you can edit the line on another thread while it is being read here. This would be a plausible answer to why my tests don't fail, as well as yours on a smaller project. Your string is not a constant, so it is technically possible that it std::istringstream

might modify it, although I see no reason why it would be.

I would change your signature to string_to_long(const std::string &str)

or copy by value and see if you are facing the same problems.



As a side note, you should always check if the error flag is set after converting text from a stream.

stream >> n;
if (stream.bad())
  throw std::runtime_error("conversion failed");

      

0


source







All Articles