1

Glib::Regex を使用しようとしていますが、ジャンクが返され続けます。

コードの簡略版は次のとおりです。

void testGetPos(std::string fileName){
    auto regEx = Glib::Regex::create(
        "^sprite_[0-9]+__x(-?[0-9]+)_y(-?[0-9]+)\\.tif$",
        Glib::REGEX_CASELESS
    )

    Glib::MatchInfo match;

    if(!regEx->match(fileName, match)){
        continue;
    }

    if(!match.matches()){
        continue;
    }

    auto posX = match.fetch(1);
    auto posY = match.fetch(2);

    // ... Use posX and posY
}

int main(){
    testGetPos("sprite_000__x-28_y-32.tif");
}

これが実行された後、posX と posY はがらくたでいっぱいになります。ただし、ラップされたオブジェクトで C 関数を使用すると、次のようになります。

void testGetPos(std::string fileName){
    auto regEx = Glib::Regex::create(
        "^sprite_[0-9]+__x(-?[0-9]+)_y(-?[0-9]+)\\.tif$",
        Glib::REGEX_CASELESS
    )

    GMatchInfo *match = nullptr;
    if(!g_regex_match(regEx->gobj(), fileName.c_str(), (GRegexMatchFlags)0, &match)){
        if(match != nullptr){
            g_match_info_free(match);
        }
        return;
    }

    auto posX = g_match_info_fetch(match, 1);
    auto posY = g_match_info_fetch(match, 2);

    // ... Use posX and posY

    g_free(posX);
    g_free(posY);
    g_match_info_free(match);
}

int main(){
    testGetPos("sprite_000__x-28_y-32.tif");
}

正常に動作します。私は何か間違ったことをしていますか、それともこれは壊れていますか。

4

1 に答える 1

1

したがって、この質問を書いた後、もう1つ試してみたところ、修正されました。他の誰かが同じ問題に遭遇した場合に備えて、ここに文書化しておく方がよいと思いました。

私は同等のものを変更しました:

void testGetPos(std::string fileName){

このようなものに:

void testGetPos(std::string _fileName){
    Glib::ustring fileName = Glib::filename_to_utf8(_fileName);

TL;DR: 暗黙的に作成された一時ファイルを に渡していたため、参照にアクセスする必要がありregEx->matchます。Glib::MatchInfoGlib::ustring

問題は次のとおりです。最初のパラメーターとしてregEx->match(fileName, match)取りますが、暗黙的に変換されていたものをconst Glib::ustring &渡していました。const std::string &ほとんどの場合、これで問題ありませんGMatchInfoが、内部のオブジェクトは match 関数に渡された文字列をコピーGlib::MatchInfo せず、オブジェクトが解放されるまでそのデータを使用できるようにする必要があります。パラメータを指定して呼び出すregEx->matchと、実行中std::stringに一時Glib::ustringオブジェクトが作成されregEx->match、終了後に破棄されます。これは、Glib::MatchInfoアクセスしているデータが無効になり、ジャンクが返されたことを意味します。を使用してGlib::filename_to_utf8、の使用を超える寿命を持つ変数を作成しますGlib::MatchInfo使用しているオブジェクトと、適切な変換関数を使用してください。

うまくいけば、これはこれに遭遇した他の人の助けになります。

于 2021-07-09T10:40:21.637 に答える