我正在使用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]以避免溢出,如果文件名太长,如Example cc reference
提前致谢。
答案 0 :(得分:5)
字符串文字(例如"IntroMusic"
)的类型为const char[N]
,可隐式转换为const char *
。通过语言设计中的错误,它也可以转换为char*
,但是在C ++中正确地弃用了该转换,因此警告。您需要使用数组(动态或静态分配),而不是字符串文字。
或者更好的是,使用std::string
。
答案 1 :(得分:2)
首先,“IntroMusic”是const。
从const值中删除const-ness并对其进行修改,未定义的行为。任何事情都可能发生,你很幸运能立刻得到崩溃。
此外,为“IntroMusic”分配的内存正好是字符的10个字节加上分隔\0
,所以总共11个字节。期。现在,除了你试图强制修改const
值之外,你甚至可以写入未分配的内存(至少,你没有为了写入而分配):你只是尝试编写你的平台依赖“IntroMusic”之后的内存文件扩展名。
您有责任为您的操作提供足够大的缓冲区。
简单解决方案(因为您标记了问题c++
,而不是c
:使用std::string
答案 2 :(得分:1)
查看strcat文档。它将目标字符串添加到源字符串。在你的情况下,源字符串是“musicFile”,所以它不应该是常量并且应该有足够的长度。
如果像这样调用函数:
PlayBackgroundIntroMusic((char *)"IntroMusic");
然后musicFile ==“IntroMusic”是不变的,不能被淹没。