Valhalla Legends Forums Archive | C/C++ Programming | strange strncpy behavior

AuthorMessageTime
Okee
I've got a function I've created that include a strncpy call. Here's my function...

[code]
char* GameIndexToName(int Index)
{
char* gamename;
//strncpy(gamename, "Starcraft Retail", 16);
switch (Index)
{
case 3:
strncpy(gamename, "Starcraft Retail", 16);
return gamename;
break;
case 6:
strncpy(gamename, "Diablo II", 9);
return gamename;
break;
default:
strncpy(gamename, "Starcraft Retail", 16);
return gamename;
break;
}
return gamename;
}
[/code]

This function compiles fine. When I run it, it crashes. I've narrowed it down to the strncpys by commenting them out. Does anyone see why this would cause the program to crash? Has to do with the pointer, I'm sure.
December 4, 2004, 10:53 PM
Mephisto
The pointer isn't pointing to allocated memory where strncpy can put what it's copying to.  You either need to do one of the following:

char gamename[SPACE_EQUAL_TO_THE_AMOUNT_YOU_NEED];
or...
char *gamename = new char[SPACE_EQUAL_TO_THE_AMOUNT_YOU_NEED];
// ...
delete [] gamename;
December 4, 2004, 11:32 PM
warz
No, he needs to learn the basics of C++ before attempting to to mess with winapi.
Okee, from your other posts I see your dabbling with winapi at an early stage in your C++ career or whatever.

change it so that it is void functionname(char* gamename, int index)

if you have char* functionname() you will have to allocate memory, you can't return the address of something declared in the function with automatic storage class.
if you declared it inside with static storage class, that would be permissable, although bad style

I'd switch it to look like this:
[code]
void GameIndexToName(char* gamename, int Index)
{
strcpy(gamename, "Starcraft Retail");
switch (Index)
{
case 1:
strcpy(gamename, "Starcraft Retail");
break;
case 0:
strcpy(gamename, "Diablo II");
break;
default:
strcpy(gamename, "Starcraft Retail");
break;
}
}
[/code]

GameIndexToName(szGameName, int iIndex);

Edit: Mephistos thing would work but I just see errors in the future if u implement that. Assertion errors or something because youd have to keep deleting gamename and stuff. *shrug*
December 4, 2004, 11:54 PM
Eibro
Nice! Someone deleted my post.
As I was saying, this situation is one where std::string comes in handy. Failing that, you could return an std::auto_ptr< char >
December 5, 2004, 5:41 AM
Myndfyr
Aren't you getting compile-time warnings?  I can't recall whether or not VC has this warning, but see my comments in your code:

[quote author=Okee link=topic=9779.msg91060#msg91060 date=1102200814]
[code]
switch (Index)
{
case 3:
strncpy(gamename, "Starcraft Retail", 16);
return gamename;
break; // Unreachable code detected.
case 6:
strncpy(gamename, "Diablo II", 9);
return gamename;
break; // Unreachable code detected.
default:
strncpy(gamename, "Starcraft Retail", 16);
return gamename;
break; // Unreachable code detected.
}
return gamename;
[/code]
[/quote]

Aside from that, you need (as I believe warz pointed out) to allocate your memory and pass it in via a pointer outside of the function.  You're thinking in Java or C#.

What you COULD do is:

[code]
/// [in, out] pGameName: pointer to allocated memory.  Outputs the game name.
/// [in] Index: game index
/// [out] nSize: length of the string
BOOL GameIndexToName(IN OUT char* pGameName, IN int Index, OUT int &nSize)
{
BOOL valid = FALSE;
switch (Index)
{
case 3:
strncpy(pGameName, "Starcraft Retail", 16);
valid = TRUE;
nSize = 16;
break;
case 6:
strncpy(pGameName, "Diablo II", 9);
valid = TRUE;
nSize = 9;
break;
default:
strncpy(pGameName, "Starcraft Retail", 16);
valid = TRUE;
nSize = 16;
break;
}
return valid;
}
[/code]
December 7, 2004, 1:22 AM
Arta
I'd do it like this, although some would consider it bad style:

[code]
const char *GameIndexToName(int Index)
{
  switch(Index)
  {
      case 3: return "Starcraft Retail";
      case 6: return "Diablo II";
      default: return "Starcraft Retail";
  }
}
[/code]

Of course, that comes with the caveat that you can't modify the returned string without copying it somewhere else first, but IMHO, that isn't usually an issue for something like this. I'd imagine this function being used mostly in places where that doesn't matter:

[code]
sprintf(Buffer, "You have selected product: %s\n", GameIndexToName(ProductIndex));
[/code]
December 7, 2004, 11:54 AM

Search