-1

Here's a sample of my code:

char chipid[13];

void initChipID(){
  write_to_logs("Called initChipID");
  strcpy(chipid, string2char(twelve_char_string));
  write_to_logs("Chip ID: " + String(chipid));
}

Here's what I don't understand: even if I define chipid as char[2], I still get the expected result printed to the logs.

Why is that? Shouldn't the allocated memory space for chipid be overflown by the strcpy, and only the first 2 char of the string be printed?

Eric
  • 477
  • 3
  • 17
  • 4
    `Shouldn't the allocated memory space for chipid be overflown by the strcpy` Yes. `and only the first 2 char of the string be printed?` No. Its undefined behavior. – tkausl Jul 11 '19 at 14:07
  • Welcome to undefined behavior land where anything is possible. – NathanOliver Jul 11 '19 at 14:07
  • Am I not risking the memory to be reallocated to another variable later, and only my first 2 char remaining securely stored? – Eric Jul 11 '19 at 14:09
  • 1
    Yes-- that is one of the several risks. Which is why it is undefined behavior. – L. Scott Johnson Jul 11 '19 at 14:12
  • 1
    @Eric Correct! The variable will flow over into address space either which is either unreserved or reserved for other variables. So you're either modifying other variables or writing to space (so far) unused. – ikkentim Jul 11 '19 at 14:12
  • `write_to_logs("Chip ID: " + String(chipid));` doesn't look like meaningful C code to me. Is this a C++ thing, or just an error? If so, please remove "C" from the tags. – Lee Daniel Crocker Jul 11 '19 at 18:06

3 Answers3

3

Here's what I don't understand: even if I define chipid as char[2], I still get the expected result printed to the logs.

Then you are (un)lucky. You are especially lucky if the undefined behavior produced by the overflow does not manifest as corruption of other data, yet also does not crash the program. The behavior is undefined, so you should not interpret whatever manifestation it takes as something you should rely upon, or that is specified by the language.

Why is that?

The language does not specify that it will happen, and it certainly doesn't specify why it does happen in your case.

In practice, the manifest ation you observe is as if the strcpy writes the full data into memory at the location starting at the beginning of your array and extending past its end, overwriting anything else your program may have stored in that space, and that the program subsequently reads it back via a corresponding overflowing read.

Shouldn't the allocated memory space for chipid be overflown by the strcpy,

Yes.

and only the first 2 char of the string be printed?

No, the language does not specify what happens once the program exercises UB by performing a buffer overflow (or by other means). But also no, C arrays are represented in memory simply as a flat sequence of contiguous elements, with no explicit boundary. This is why C strings need to be terminated. String functions do not see the declared size of the array containing a string's elements, they see only the element sequence.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
2

You have it part correct: "the allocated memory space for chipid be overflowed by the strcpy" -- this is true. And this is why you get the full result (well, the result of an overflow is undefined, and could be a crash or other result).

L. Scott Johnson
  • 4,213
  • 2
  • 17
  • 28
1

C/C++ gives you a lot of power when it comes to memory. And with great power comes great responsibility. What you are doing gives undefined behaviour, meaning it may work. But it will definitely give problems later on when strcpy is writing to memory it is not supposed to write to.

You will find that you can get away with A LOT of things in C/C++. However, things like these will give you headaches later on when your program unexpectedly crashes, and this could be in an entire different part of your program, which makes it difficult to debug.

Anyway, if you are using C++, you should use std::string, which makes things like this a lot easier.

SilverTear
  • 695
  • 7
  • 18