3

私はLinuxを使用しています。

次のような関数があります。

PlayBackgroundIntroMusic((char *)"IntroMusic");

機能は次のとおりです。

ボイド サウンド マネージャー::
PlayBackgroundIntroMusic( char * musicFile)
{
        // 各プラットフォームの拡張子を連結
        strcat (musicFile,audioExtension);
        CCLOG("musicFile: %c" musicFile);
  SimpleAudioEngine::sharedEngine()->playBackgroundMusic(std::string(CCFileUtils::fullPathFromRelativePath(musicFile)).c_str(), false);
}

しかし、オンラインでメモリへのアクセスが悪い:

strcat (musicFile,audioExtension);

audioExtension が宣言されています:

#含む
std::string の使用;
#含む
std::cout; の使用 std::cerr を使用します。std::endl の使用;

/**
 * プラットフォームごとにサウンド拡張を宣言
 * アンドロイド = ogg
 ※iOS=カフェ
 * WIN32 = mp3
 */

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
        static const char * audioExtension = ".wav";
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
        static const char * audioExtension = ".caf";
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        static const char * audioExtension = ".ogg";
#endif

だから、私は持っていると思っていました:

iOS の IntroMusic.caf
Android の IntroMusic.ogg

何が起こっているのですか?

注:私はしようとしました:

char * musicFileWithExtension = strcat (musicFile,audioExtension);

しかし、とにかくうまくいきませんでした。

musicFile は定数ではありません。ファイルの名前が長すぎる場合のオーバーフローを避けるために tempchar[80] を宣言したくない例 cc リファレンス

前もって感謝します。

4

3 に答える 3

5

などの文字列リテラルは、暗黙的に に変換可能な"IntroMusic"型です。言語設計の誤りにより、 にも変換できますが、その変換は C++ では正当に非推奨であるため、警告が表示されます。文字列リテラルではなく、(動的または静的に割り当てられた) 配列を使用する必要があります。const char[N]const char *char*

またはさらに良いことに、を使用しますstd::string

于 2012-06-22T07:17:53.053 に答える
2

まず、「IntroMusic」は const です。

const 値から const-ness を削除して変更することは、未定義の動作です。何かが起こるかもしれませんが、すぐにクラッシュするのは幸運です。

さらに、"IntroMusic" に割り当てられるメモリは、文字と区切り文字の正確に 10 バイトな\0ので、合計で 11 バイトになります。限目。ここで、値の変更を強制しようとするconstだけでなく、割り当てられていないメモリに書き込むことさえあります (少なくとも、書き込み目的で割り当てられたものではありません): プラットフォームに依存するファイル拡張子をメモリに書き込もうとするだけです。 「IntroMusic」の後。

操作に十分な大きさのバッファーを提供する責任があります。

簡単な解決策(質問にタグを付けたのでc++、ではなくc:を使用std::string

于 2012-06-22T07:20:15.537 に答える
1

strcat のドキュメントを参照してください。ソース文字列に宛先文字列を追加しています。あなたの場合、ソース文字列は「musicFile」であるため、一定ではなく、十分な長さでなければなりません。

関数が次のように呼び出された場合:

PlayBackgroundIntroMusic((char *)"IntroMusic");

musicFile == "IntroMusic" は定数であり、上書きできません。

于 2012-06-22T07:18:04.530 に答える