3

I have a static variable declared in a file:

static char *msgToUser[] = {
    "MSG1                ", 
    "MSG2                ",
};

Inside one of the methods of a class I'm doing this:

void InfoUser::ModifyMsg( BYTE msgIdx, char *msgString ){
    strncpy( msgToUser[ idx ], msgString, DISPLAY_SIZE );
}

When I do the strncopy the program crashes. I'm not sure what I'm doing wrong

codaddict
  • 445,704
  • 82
  • 492
  • 529
Megacan
  • 2,510
  • 3
  • 20
  • 31

4 Answers4

6

The array you have defined is an array of pointers to character strings; each character string is a literal (ie, a quoted string interpreted as a pointer) - this means it's a constant, even if you didn't declare it as such. You cannot modify string literals.

If you want to be able to modify them, you can use an explicit array allocation:

// Note: The space padding isn't needed if all you require is that the string
// be able to hold DISPLAY_SIZE characters (incl the null terminator)
static char str_1[DISPLAY_SIZE] = "MSG1                ";
static char str_2[DISPLAY_SIZE] = "MSG1                ";
static char *msgToUser[] = { str_1, str_2 };
bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • 1
    In this case, is it even required to initialize them with dummy values? Ain't `static char str_1[SIZE]` enough? – Amarghosh Aug 30 '10 at 12:39
  • Indeed it is, in which case the string would be initialized to an empty string (all zeroes). I wasn't sure if the OP wanted the MSG1/MSG2s in, so I left them, but if an initially empty string works that's fine too. – bdonlan Aug 30 '10 at 12:47
  • 1
    +1, but I would have gone with `static char msgToUser[][DISPLAY_SIZE] = { "...", "..." };`. – schot Aug 30 '10 at 13:09
  • @schot, the semantics there are slightly different - in particular, you can't use it as a `char **`. It is more convenient to type though. – bdonlan Aug 30 '10 at 13:41
2

See C-FAQ. Question 1.32

matli
  • 27,922
  • 6
  • 37
  • 37
0

Instead of keeping your array as an array of pointers, make it a two dimensional array of characters which will make it allocate space.

Now, since it is an array of char * and initialization is happening using string literals, when you try to overwrite read only memory of string literals, it crashes.

Jay
  • 24,173
  • 25
  • 93
  • 141
0

You have defined msgToUser as a vector of char-pointers. These char-pointers point to strings (character arrays) that are stored in memory that has been marked as read-only (In Microsoft's Visual Studio you can change this via a compiler option).

Therefore, if you change this memory, the processor will raise an exception (you are trying to write in read-only memory) and your application will crash.

Patrick
  • 23,217
  • 12
  • 67
  • 130