问题
I'm using linux.
I have a function called like:
PlayBackgroundIntroMusic((char *)"IntroMusic");
The functions is:
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); }
But i having a bad access to memory on line:
strcat (musicFile,audioExtension);
audioExtension is declarated:
#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
So, i expected to have:
IntroMusic.caf on iOS IntroMusic.ogg on Android
What's is happening?
NOTE: I have tried to:
char * musicFileWithExtension = strcat (musicFile,audioExtension);
But it didn't work anyway.
musicFile is not a constant. I don't want to declarate a tempchar[80] to avoid overflow if the name of the file is too long like Example cc reference
Thanks in advance.
回答1:
String literals, such as "IntroMusic"
are of type const char[N]
which is implicitly convertible to const char *
. Through a mistake in language design, it is also convertible to char*
, but that conversion is rightfully deprecated in C++, hence the warning. You need to use an array (dynamically or statically allocated), not a string literal.
Or better yet, use std::string
.
回答2:
First of all, "IntroMusic" is const.
Removing const-ness from a const value and modify it, is undefined behaviour. Anything might happen, you are lucky to get the crash right away.
Furthermore, the memory allocated for "IntroMusic" is exactly 10 bytes for the characters plus a delimiting \0
, so in total 11 bytes. Period. Now, besides you trying to force a modification of a const
value, you even write to unallocated memory (at least, not allocated by you for the purpose of writing to it): You simply try to write your platform-dependent file extension to the memory after "IntroMusic".
You are responsible to provide a sufficiently large buffer for your operation.
Simple solution (since you tagged the question c++
, not c
: use std::string
回答3:
Look at the strcat documentation. It is adding destination string to the source string. In your case source string is "musicFile", so it should not be constant and should have enough length.
if function is called like this:
PlayBackgroundIntroMusic((char *)"IntroMusic");
then musicFile == "IntroMusic" is constant and cannot be overwrited.
来源:https://stackoverflow.com/questions/11151626/bad-access-to-memory-using-strcat