-1

I'm working on an app that has strings in an array like:

static char * strings[] = {
  "ABC DEF",
  "EF",
  "GHI"
};

Note, that the type doesn't have const modifier!

In my app I loop over the array and revert the strings. The expected result is:

{
  "FED CBA",
  "FE",
  "IHG"
}

However the result I get is:

{
  "FED CAB",
  "AB",
  "IHG"
}

The reason for this is because in the original array the strings are compiled to overlap: strings[1] overlaps the end of strings[0]!!!

// When I printed out the pointers it turned out that in the RAM
// it stored my strings "overlapping":
//  00 01 02 03 04 05 06 07 08 09 0a 0b
// "A  B  C  __ D  E  F  \0 G  H  I  \0"

static char * strings[] = {
  0x00, 0x05, 0x08
};

Is there any way (besides not having the const modifier which doesn't work) to tell the compiler not to overlap my strings? Is this a bug in the compiler or in my code? What workaround can I do?

JJJ
  • 32,902
  • 20
  • 89
  • 102
Gavriel
  • 18,880
  • 12
  • 68
  • 105
  • 8
    Modifying string literals is UB. Your code is broken. – melpomene Nov 04 '16 at 10:34
  • 2
    Possible dup:http://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-string-initialized-with-cha – P.P Nov 04 '16 at 10:36
  • @Lundin OP doesn't get a seg fault. – 2501 Nov 04 '16 at 10:39
  • This question doesn't have anything to do with Pebble. Please stop adding those tags. – JJJ Nov 04 '16 at 10:41
  • 1
    @2501 That's because he gets undefined behavior. Perhaps this is a better duplicate? [What is the difference between char s and char *s in C?](http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c). – Lundin Nov 04 '16 at 10:41
  • @2501 well, it is probably because in pebble it's not protected from writes. – Gavriel Nov 04 '16 at 10:41
  • 4
    Oh come on, this is definitely a duplicate, this question is asked like 5 times per day. – Lundin Nov 04 '16 at 10:45

1 Answers1

6

You're getting undefined behavior since you're modifying a string implemented as a char * pointing at a string literal, that's not valid.

You must have them in explicit arrays, to make sure they are modifiable:

static char str1[] = "ABC DEF", str2[] = "EF", str3[] = "GHI";
static char * strings[] = { str1, str2, str3 };

Note that all of the str strings have type char [], not char * so they are proper arrays. Non-const arrays, of course, are always modifiable.

If you're willing to commit to a maximum string length, you can do a 2D array type of declaration to get it more compact:

static char strings[][10] = { "ABC DEF", "EF", "GHI" };

By the way, this question is pretty much an XY problem.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
  • Ok I understand my problem, but is there a way to write the working version with [] it shorter form? Something like: static char strings[][] = {"foo", "bar"}; without the need to change the code too much? – Gavriel Nov 04 '16 at 11:10
  • @Gavriel Yes, updated. Feel free to accept this answer. :) – unwind Nov 04 '16 at 11:13
  • the problem is that I have 90+ strings varying in size quiet a bit, and since it's a pebble app, I would still try to keep it low in memory footprint, but adding 90 variables is something I'd like to avoid if possible. (though I guess that wouldn't really change the binary size, just the source code, right?) Can it be done using macros? – Gavriel Nov 04 '16 at 11:28
  • @Gavriel "That depends". It most likely will affect total memory use at run-time, since the literals have to be stored somewhere and perhaps copied into the arrays. If the lengths of the 90 strings are close (i.e. it's not 30 3-character strings and 70 100-character ones) you could use the array solution I added. That will waste memory by making all strings the same in-memory length though. – unwind Nov 04 '16 at 12:05
  • Yes, I understood that part with the allocated and unused chars in case of char[N][L] {and I prefer not to have that since my strings vary from 3-16 2-byte chars, and I just checked it would almost double the allocated memory}, what I was hesitating about is whether having 90 pointers (str1, str2,...) will add to the memory usage or they actually only exist in the compiler (and well the 90 pointers should be stored in the array but that's the case even with my broken code now) – Gavriel Nov 04 '16 at 12:29