-1

If I declare 2 arrays arr1 and arr2 in C (on Windows) and fill arr1 with integers 0 to 15, some of the overflow goes to arr2, but not all of it. Why?

  int arr1[10];
  int arr2[10];
  int arr3[10];
  int i;

  for (i = 0 ; i < 10 ; i++)
    {
     arr1[i] = 100 + i;
     arr3[i] = 300 + i;
    }

  for (i = 0 ; i < 15 ; i++)
    {
     arr2[i] = 200 + i;
    }

  printf ("arr1: ");
  for (i = 0 ; i < 10 ; i++)
    printf ("%d, ", arr1[i]);
  printf ("\n");

  printf ("arr2: ");
  for (i = 0 ; i < 10 ; i++)
    printf ("%d, ", arr2[i]);
  printf ("\n");

  printf ("arr3: ");
  for (i = 0 ; i < 10 ; i++)
    printf ("%d, ", arr3[i]);
  printf ("\n");

Output:

arr1: 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 
arr2: 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 
arr3: 212, 213, 214, 303, 304, 305, 306, 307, 308, 309, 

Expected:

arr1: 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 
arr2: 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 
arr3: 210, 211, 212, 213, 214, 305, 306, 307, 308, 309,
Martin
  • 16,093
  • 1
  • 29
  • 48
thegoodhunter-9115
  • 317
  • 1
  • 3
  • 15
  • 4
    Because there's no guaranteed outcome whatsoever with undefined behavior. It could do what you expect it to do, it could crash the program, or something totally different. It doesn't even have to be consistent in any form. Just don't do it, it's not useful or practical, and it's just going to be a headache when it stops working and causes hard to debug issues such as memory corruption. – Blaze Sep 10 '19 at 14:23
  • When you are overwriting the array, you are simply writing into the memory address for the start of the array plus _i_ * the size of int. How do you know where the other arrays are allocated? Why would you assume they simply stack one after another in memory? – Martin Sep 10 '19 at 14:25
  • It will be because the compiler is aligning the arrays to 16-byte boundaries, = 4 integers. If you used a multiple of 4 instead of 10 then they'll likely just flow into each other. But this behaviour can vary from OS to OS and compiler to compiler, so don't rely on it (and don't do it full stop). If you need arr1,2,3 to be continguous then allocate a single block of memory and assign arr2 and arr3 to point to the places you want. – Rup Sep 10 '19 at 14:27
  • 1
    Undefined behavior isn't strictly random, but it might as well be. Asking why you don't get the behavior you "expect" is like asking, "Last night I crossed the street when the sign said DON'T WALK. I expected to get a jaywalking ticket from a policeman. Instead I got run over by a truck. Why?" – Steve Summit Sep 10 '19 at 14:33

3 Answers3

0

If you exceed the size of an array, C will just lead you to undefined behavior.

The definition of undefined behavior:

C11(ISO/IEC 9899:201x) §3.4.3

1 undefined behavior

behavior, upon use of a non portable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

3 EXAMPLE An example of undefined behavior is the behavior on integer overflow.

There is also a list of undefined behaviors in C11 §J.2 Undefined behavior

Here your arrays were just packed in the memory.

If I run this program on my computer with another linux distribution and another compiler I will probably not have the same result as yours as this is undefined behavior.

Remember to avoid undefined behavior

LucasFab
  • 95
  • 10
  • Is there a rule how global variables are arranged in memory ? – A.Franzen Sep 10 '19 at 14:30
  • @A.Franzen No, variables are just stored in the memory where you have enough space, here the array could have been at 3 really different places and we would not have seen this behavior but another one – LucasFab Sep 10 '19 at 14:35
0

This likely happened because your arr3 happened to be 2 positions after arr2 in memory, so it wrote 210 and 211 in these (possibly empty or used by another variable-program) and started overwriting arr3 by putting 212 in its first cell.

However, as others already said, this behavior is totally random and should be avoided (you never know if arr3 will be declared 1 or 20 or 10000 positions in memory after arr2)

liakoyras
  • 1,101
  • 12
  • 27
0

What's most likely here is that some other part of the program managed to allocate the 8 (or 16, depending on architecture) bytes in memory directly after arr2, so arr3 ended up being allocated after those bytes. Therefore, when you wrote 210 and 211, those actually overwrote that other memory before the remainder were written to arr3.

Rob Streeting
  • 1,675
  • 3
  • 16
  • 27
  • Nah, i dont think that's right. Global variables have their space in the objectfile, they are not dynamically allocated. For some reason the compiler put something in there between the two arrays. – A.Franzen Sep 10 '19 at 14:36