-1

I'm trying to set some string variables like this:

char thingA[7], thingB[7], thingC[7];
strcpy(thingA, "StringA");
strcpy(thingB, "StringB");
strcpy(thingC, "StringC");
printf("%s\n", thingA);
printf("%s\n", thingB);
printf("%s\n", thingC);

but instead of outputting like this:

StringA  
StringB  
StringC  

it outputs like this:

StringA StringB StringC  
StringB StringC  
StringC 

I've tried this with sprintf, but get the same result. I honestly have no idea what's going on, or how to fix this, and I can't find anything on it online, since searching for this kind of stuff has proven hard for some reason. So basically why is it storing string b and c in a, and c in b?

KelvinS
  • 2,870
  • 8
  • 34
  • 67
Matthew
  • 185
  • 1
  • 12
  • A string with seven characters has length of 8, due to null terminatior. – Sergey Kalinichenko Jun 08 '17 at 17:29
  • @dasblinkenlight-- wouldn't it be better to say that a string with seven characters has _size_ 8, but lenth (as returned by `strlen()`) 7? Then again, I guess a string with 7 characters should really have length 6, since `\0` is part of the string.... – ad absurdum Jun 08 '17 at 17:43

2 Answers2

2

The usual error: your declarations are one byte short. If you count the characters in your constant strings, there are 7, and you need space for the terminating'\0', otherwise you will overwrite memory and get undefined bahvaior.

So declare them as [8], and it will work.

Aganju
  • 6,295
  • 1
  • 12
  • 23
  • So why doesn't it just add one character of the next string, instead of the entire string. (Or better yet, why does it even copy the strings below it instead of just returning an error?) – Matthew Jun 08 '17 at 17:31
  • And even be generous until you see you are getting tight on memory. – Weather Vane Jun 08 '17 at 17:31
  • 2
    @Magicrafter13Gaming , C is designed for efficiency. No length and overflow testing like in other languages is done, to enable max speed. It is the developer's job to do it right. – Aganju Jun 08 '17 at 17:33
  • @Magicrafter13Gaming what you did causes undefined behaviour - no strings "were copied". It is futile to discuss why your result happened. – Weather Vane Jun 08 '17 at 17:34
  • It doesn't return an error because it has no way of knowing there is an error. No information is stored internally on the length of a string; it's just a naked reserved section of memory. All strcpy does is blindly copy successive memory locations until it sees a zero byte. – Vercingatorix Jun 08 '17 at 17:45
1

The problem with the code is that you strings in C are null terminated (\0), so StringA, despite having 7 printable characters, actually needs 8 chars to store. The three char arrays are back to back on the stack, so overwriting the terminating null character will result in them being concatenated. Each pointer to the char array starts at a different offset, hence the shorter strings for thingB and thingC, but in all cases printf will read the string until it finds a null character after the end of thingC.

Notice that this is a classic buffer overflow bug, and you are just lucky that there is a null on the stack after thingC, otherwise printf would have continued reading and printing memory way longer.

cdecker
  • 4,515
  • 8
  • 46
  • 75