我在用Linux。
我有一个函数叫like:
PlayBackgroundIntroMusic((char *)"IntroMusic");
其功能是:
void SoundManager:: PlayBackgroundIntroMusic( char * musicFile) { // Concatenate extension for each platform strcat (musicFile,audioExtension); CCLOG("musicFile: %c" musicFile); SimpleAudioEngine::sharedEngine()->playBackgroundMusic(std::string(CCFileUtils::fullPathFromRelativePath(musicFile)).c_str(), false); }
但我无法访问在线内存:
strcat (musicFile,audioExtension);
声明audioExtension:
#include using std::string; #include using std::cout; using std::cerr; using std::endl; /** * Declare sound extension for each platform * Android = ogg * iOS = caf * 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
所以,我希望有:
IntroMusic.caf on iOS IntroMusic.ogg on Android
发生什么事了?
注意:我已尝试:
char * musicFileWithExtension = strcat (musicFile,audioExtension);
但无论如何都没用。
musicFile不是常量。我不想声明一个tempchar[80]以避免文件名太长时溢出,如示例cc引用
提前道谢。
字符串文字(如“intromusic”
)的类型为const char[N]
,可隐式转换为const char*
。由于语言设计中的一个错误,它也可以转换为char*
,但这种转换在C++中是正确的,因此提出了警告。您需要使用数组(动态或静态分配),而不是字符串文字。
或者使用std::string
更好。
首先,“Intromusic”是常量。
从常量值中删除常量并修改它是未定义的行为。任何事情都有可能发生,你很幸运马上就被撞车了。
此外,为“IntroMusic”分配的内存正好是10个字节的字符加上一个限定符\0
,因此总共是11个字节。句号。现在,除了尝试强制修改const
值之外,您甚至会写入未分配的内存(至少,不是您为写入该内存而分配的):您只需尝试将与平台相关的文件扩展名写入“intromusic”之后的内存。
您有责任为您的操作提供足够大的缓冲区。
简单的解决方案(由于您将问题标记为C++
,而不是C
:使用std::string
查看strcat文档。它正在将目标字符串添加到源字符串中。在您的示例中,源字符串是“musicfile”,因此它不应该是常量,并且应该有足够的长度。
如果函数是这样调用的:
PlayBackgroundIntroMusic((char *)"IntroMusic");
则musicFile==“intromusic”为常量,不能覆盖。