这个人有我。我正在尝试编写一个模板化函数,用于将字符串转换为不同的数据类型。它必须能够在12个不同的平台上编译,因此使用boost不是一个方便的选择。我已经退回到只有一个将字符串转换为long的函数。这是它看起来的基本版本......
long string_to_long(string &str) {
istringstream stream(str);
long n;
stream >> n;
return n;
}
使用模板化函数和这个更具体的函数,一旦创建istringstream,我就会得到一个糟糕的内存访问。如果我初始化istringstream而不传递str变量,它仍然会崩溃。我的堆栈跟踪看起来像这样......
(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)
我尝试将string_to_long()添加到只有主函数的空白C ++项目中。它在这种情况下工作正常。在我正在使用此功能的应用程序中,在某些位置添加对它的调用将随机用于一个调用,并在下一个调用时崩溃。我一直在用这个电话来测试它,它会偶尔成功一次。
string num = "1234";
long long_val = string_to_long(num);
我完全没有想法。看起来它与编译,链接或堆栈问题有关。
这个文件可能很重要,包括......
#include <fstream>
#include <sstream>
#include "myfile.h"
...和myfile.h(名字明显不含)包括......
#include <map>
#include <string>
#include "rapidxml/rapidxml.hpp"
我仍然不知道造成这种情况的原因。我花了几天修修补补。我正在Netbeans的Mac OS Lion上开展这个项目。当我使用netbeans生成的相同makefile在Linux和Solaris上编译和运行它时,它很好。
就istringstream问题而言,我将istringstream create从函数调用中拉出来并使其成为私有成员变量。我并不是因为拥有更多的成员变量而不是绝对必要,但在这种情况下,它是一种解决方法。它也会减少对象的创建。
当我使用istringstream转换int / long / short,然后使用相同的流来转换float或double时,崩溃问题仍然存在问题。这是我确定的代码。如果我弄清楚Mac OS特有的问题,我会发布更新。
这是我现在解决的代码。我不想知道造成这种情况的原因。
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;
}
答案 0 :(得分:0)
考虑到你在崩溃堆栈中有线程处理,你可能正在从这里读取另一个线程中的字符串。对于我的测试没有失败的原因,这也是一个合理的答案,在较小的项目中也是如此。你的字符串不是常量,所以std::istringstream
在技术上可能会修改它,虽然我认为没有任何理由。
我会将您的签名更改为string_to_long(const std::string &str)
或按值复制,看看您是否遇到同样的问题。
作为旁注,您应该始终检查在从流中进行文本转换后是否设置了坏标记。
stream >> n;
if (stream.bad())
throw std::runtime_error("conversion failed");