1

c文字列のベクトルをc文字列の配列に変換しようとしています。これを試しましたが、正しく機能していないようです。

int glfxGetProgramList(int effect, char** progList, int* count)
{
    std::vector<char*> list;
    gEffects[effect]->GetProgramList(list);
    fprintf(stderr, "Lib Output: %s\n", list[0]);
    progList = &list[0];
    int size = list.size();
    memcpy(count, &size, sizeof(int));
}

stderrから返されるデバッグ出力は、関数内で正しいものです。ただし、プロジェクト内でこの関数を使用してリストの最初の項目を出力しようとすると、セグメンテーション違反でクラッシュします。これが私のプロジェクトのコードです:

char ** list;
int size;
glfxGetProgramList(effect, list, &size );
fprintf(stderr, "Output: %s\n", list[0]);

私が間違っていることについて何か考えはありますか?

編集:

問題の根底から始めなければならないと思います。名前のリストを取得しようとしているプラ​​イベートマップ配列があります。GetProgramListのコードは次のとおりです。

unsigned Effect::GetProgramList(vector<char*>& list) const
{
    for(map<string,Program*>::const_iterator it=m_programs.begin(); it!=m_programs.end(); ++it)
        list.push_back( (char*)it->first.c_str() );
}
4

3 に答える 3

3

このようにアクセスできますchar**(ただし、コンパイラがC ++ 11をサポートしている場合のみ)。

    progList = list.data();
于 2013-01-04T21:18:12.400 に答える
2

なんでキャストするの?

最初の要素のアドレスchar *は自動的にchar **、キャストする必要はありません。これが機能しない場合は、の定義を投稿してくださいprogList。ベクトルが空の場合、これにより未定義の動作が発生し、アプリケーションがクラッシュする可能性があります。list.size()それが0より大きい(または!list.emty()-より良い)ことを確認してください。

于 2013-01-04T21:12:55.147 に答える
1

これ:

 progList = &list[0];

完全に動作するはずです。

しかし理由は:

std::vector<char*> list;

関数に対してローカルであり、関数がアクティブな間のみ有効です。関数が返されると、ポインターは無効になります (ベクトルが存在しなくなるため)。

progList私がこれに言及する理由は、ここで out パラメータとして使用しようとしているように見えるからです:

int glfxGetProgramList(int effect, char** progList, int* count)


// Because you call like this:  
glfxGetProgramList(effect, list, &size );  // The value of list will not change
                                           // as you are passing by value.

fprintf(stderr, "Output: %s\n", list[0]);  // So here list has not changed.
                                           // But also note it would not have worked
                                           // as the object you were trying to make it 
                                           // point at would have gone out of scope.

残念ながら (または幸いなことに)、これらのパラメーターは参照ではないため、ローカルで行った変更は関数の外部の元の値には影響しません。

したがって、いくつかのことを修正する必要があります。

  • 関数の呼び出しよりもベクトルを長持ちさせる
  • 参照によってリストを関数に渡します。

試す:

int glfxGetProgramList(int effect, char**& progList, int* count)
                               //        ^  pass by reference
{
    static std::vector<char*> list; // Static makes the list last past the end of the function
    list.clear();                   // Now we have to clear it each time we call to make sure
                                    // that old results do not pollute the list.

    gEffects[effect]->GetProgramList(list);
    fprintf(stderr, "Lib Output: %s\n", list[0]);

    progList = &list[0];       // Value now passed correctly
                               // back to the calling function
                               // and list will still exist.

    int size = list.size();
    memcpy(count, &size, sizeof(int));  // This copies the first value out
}
于 2013-01-04T22:08:35.747 に答える