-3

In C, if I initialize a char array like this:

char lines[5];
memcpy((char *)line,"Hello",5)

Then if I execute the following expression:

line[6]='\0';

Would this cause buffer overflow? Thanks?

XIN LIU
  • 87
  • 1
  • 9
  • 4
    Of course it will. Everything after `line[4]` is outside the array. – Barmar Apr 27 '18 at 01:30
  • 1
    Why do you write `(char *)line`? That's already its type. – Barmar Apr 27 '18 at 01:31
  • 4
    And why `line[6]` instead of `line[5]`? – Barmar Apr 27 '18 at 01:31
  • This is the very definition and a canonical example of "buffer overflow". Wat makes you think it is not? – Jongware Apr 27 '18 at 01:33
  • 1
    Even `lines[5]='\0'` would be an overflow. When you said `char lines[5]`, that got you `lines[0]` through `lines[4]`. – Steve Summit Apr 27 '18 at 01:33
  • Should `lines[5]` be `line[5]`? – Barmar Apr 27 '18 at 01:33
  • Array indexes (indices?) in C are 0-based. Your declaration `char lines[5];` declares a 5-character array. Valid index values for that array will be 0 to 4. After loading it with 'H', 'e', 'l', 'l', and 'o' there is no room left to write a '\0'. – STLDev Apr 27 '18 at 01:35
  • As you probably know, the right thing to do here, if you want a proper, null-terminated string, would be to declare `char line[6]` and then `memcpy(line, "Hello", 6)`. – Steve Summit Apr 27 '18 at 01:36
  • 1
    Yes, accessing `line[6]` for reading or for writing will cause *undefined behavior*. Since you declared `line` array to have five elements, valid indexes are 0, 1, 2, 3, and 4. The last index you can safely assign is `4`. – Sergey Kalinichenko Apr 27 '18 at 01:38
  • Would the complier assign 8 bytes for 'lines'? Since 8 is a multiple of 4(the possible word length). – XIN LIU Apr 27 '18 at 01:41
  • 2
    @XINLIU No. Nothing like that. If you ask for 5, you get 5. – Steve Summit Apr 27 '18 at 01:55
  • "Padding" of variable space is an implementation-specific issue, and not required at all. In the past, there was no such thing (you ask 5 bytes, you get 5 bytes, and the next variable allocated is at the very next byte). In the future, padding may go up to 16 or 32 or 4,096 bytes. – Jongware Apr 28 '18 at 09:18

3 Answers3

1

Many problems. For one, why cast to char *, when that is to what the array decays? Second, you need to use a zero-based index, not a one-based index; The first element of array a is a[0] not a[1].

Also you should have set the buffer size to 6, not 5, to make room for terminator

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
  • The way how the OP explain through its Question it is more over “2 based index” :))) – Michi Apr 27 '18 at 03:31
0

Then if I execute the following expression:

line[6]='\0';

Would this cause buffer overflow?

Yes. Because lines contains five characters and you are overwriting the seventh one.

Would the comp[il]er assign 8 bytes for 'lines'?

No.

It might put 3 bytes of padding after lines, in which case it's still a buffer overflow because lines is still 5 bytes long.

Community
  • 1
  • 1
user253751
  • 57,427
  • 7
  • 48
  • 90
0

You are definitely writing outside the bounds of the array, which leads to undefined behavior. The result could be any of the following:

  • a runtime error (segfault);
  • corrupted data (overwriting part of another object);
  • behaving exactly as expected

Most platforms have alignment requirements such that there may be some unused bytes between the end of the array and the next object in memory1, and writing one or two bytes past the end of the array isn't much of an issue. But that's not the same thing as the compiler allocating "extra space" for the array.


  1. Assuming the array size isn't a multiple of 2 or 4 bytes, anyway.

WedaPashi
  • 3,561
  • 26
  • 42
John Bode
  • 119,563
  • 19
  • 122
  • 198