【问题标题】:Bad access to memory using strcat使用 strcat 对内存的错误访问
【发布时间】:2012-06-24 11:35:00
【问题描述】:

我正在使用 linux。

我有一个函数叫做:

PlayBackgroundIntroMusic((char *)"IntroMusic");

功能是:

无效的声音管理器:: PlayBackgroundIntroMusic(char * musicFile) { // 为每个平台连接扩展 strcat(音乐文件,音频扩展); CCLOG("musicFile: %c" musicFile); SimpleAudioEngine::sharedEngine()->playBackgroundMusic(std::string(CCFileUtils::fullPathFromRelativePath(musicFile)).c_str(), false); }

但我无法在线访问内存:

strcat(音乐文件,音频扩展);

声明了audioExtension:

#包括 使用标准::字符串; #包括 使用 std::cout;使用 std::cerr;使用 std::endl; /** * 为每个平台声明声音扩展 * 安卓 = ogg * iOS = 咖啡馆 * WIN32 = mp3 */ #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) 静态 const char * audioExtension = ".wav"; #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 静态 const char * audioExtension = ".caf"; #elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 静态 const char * audioExtension = ".ogg"; #万一

所以,我希望有:

iOS 上的 IntroMusic.caf Android 上的 IntroMusic.ogg

发生了什么事?

注意:我已尝试:

char * musicFileWithExtension = strcat (musicFile,audioExtension);

但还是没用。

musicFile 不是一个常数。如果文件名太长,如Example cc reference

,我不想声明 tempchar[80] 以避免溢出

提前致谢。

【问题讨论】:

  • 你的编译器试图告诉你一些事情。然后为了让它闭嘴,你添加了一个演员表。也许你应该听过。
  • 没有演员表也能工作吗?练习:找出原因。
  • 如果没有 (char *) 演员表,则会发送警告,取消创建转换,所以我进行演员表。到底是怎么回事?转换字符串有什么不好的用途吗?
  • 您试图在没有存储空间的情况下连接某些东西。 AFAIR 一个普通的字符串文字的类型为“n const char 数组” - 来自 C++ 标准。

标签: c++ std string-concatenation cocos2d-x


【解决方案1】:

字符串字面量,例如"IntroMusic"const char[N] 类型,可以隐式转换为const char *。由于语言设计中的错误,它也可以转换为char*,但这种转换在 C++ 中被正确弃用,因此发出警告。您需要使用数组(动态或静态分配),而不是字符串文字。

或者更好的是,使用std::string

【讨论】:

    【解决方案2】:

    首先,“IntroMusic”是常量。

    从 const 值中移除 const 特性并对其进行修改是未定义的行为。任何事情都可能发生,你很幸运能立即得到崩溃。

    此外,为“IntroMusic”分配的内存正好是字符的 10 个字节加上分隔符 \0,所以总共 11 个字节。时期。现在,除了您尝试强制修改 const 值之外,您甚至写入未分配的内存(至少,您没有为写入它而分配):您只需尝试编写与平台相关的文件扩展名到“IntroMusic”之后的记忆。

    您有责任为您的操作提供足够大的缓冲区。

    简单的解决方案(因为您标记了问题c++,而不是c:使用std::string

    【讨论】:

      【解决方案3】:

      查看 strcat 文档。它正在将目标字符串添加到源字符串。在您的情况下,源字符串是“musicFile”,因此它不应该是恒定的并且应该有足够的长度。

      如果函数是这样调用的:

      PlayBackgroundIntroMusic((char *)"IntroMusic");
      

      那么 musicFile == "IntroMusic" 是常量,不能被覆盖。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多