3

これは私を持っています。文字列をさまざまなデータ型に変換するためのテンプレート関数を作成しようとしています。12の異なるプラットフォームでコンパイルできる必要があるため、boostを使用するのは便利なオプションではありません。文字列をlongに変換する関数を使用するようになりました。これがその外観の非常に基本的なバージョンです...

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

テンプレート化された関数とこのより具体的な関数の両方を使用すると、istringstreamを作成するとすぐにメモリアクセスが悪くなります。str変数を渡さずにistringstreamを初期化すると、クラッシュします。私のスタックトレースは次のようになります...

(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)

main関数しかない空のC++プロジェクトにstring_to_long()を追加してみました。そのシナリオでは正常に機能します。私がこの関数を使用しているアプリでは、特定の場所に呼び出しを追加すると、1つの呼び出しでランダムに機能し、次の呼び出しでクラッシュします。私はそれをテストするためにこの呼び出しを使用してきました、そしてそれは時々成功するでしょう。

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のMacOSLionでこのプロジェクトに取り組んでいます。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;
}
4

1 に答える 1

0

クラッシュスタックにスレッド処理があることを考えると、ここから読み取っている間に別のスレッドで文字列を編集している可能性があります。これは、私のテストが失敗しない理由や、小規模なプロジェクトでのテストが失敗しない理由についてのもっともらしい答えになります。あなたの文字列はconstではないので、技術的にはそれをstd::istringstream変更している可能性がありますが、そうする理由はわかりません。

署名を値に変更するstring_to_long(const std::string &str)か、値でコピーして、同じ問題が発生するかどうかを確認します。

補足として、ストリームからのテキスト変換後に不良フラグが設定されているかどうかを常に確認する必要があります。

stream >> n;
if (stream.bad())
  throw std::runtime_error("conversion failed");
于 2012-03-19T17:56:09.207 に答える