0

Consider this code:

#include <stdio.h>

int main() {
    
    static arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
    for(int i = 2; i < 50; i++)
    {
        arr[arr[i]] = arr[i] + i;
    }
    for(int i = 0; i < 50; i++)
    {
        printf("%d\n", arr[i]);
    }

    return 0;
}

It gives successful output for 50 elements. But the array had 8 elements. WHY no segmentation fault??

and this code:

#include <stdio.h>

int main() {
    
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
    for(int i = 2; i < 50; i++)
    {
        arr[arr[i]] = arr[i] + i;
    }
    for(int i = 0; i < 50; i++)
    {
        printf("%d\n", arr[i]);
    }

    return 0;
}

It gives segmentation fault as expected.

Please explain to me what static arr[] is doing. I'm a beginner and as far as I know, a data type is required. Here, instead static is used.

In the first code, I don't really understand what is happening.

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • 1
    This declaration static arr[] = {1, 2, 3, 4, 5, 6, 7, 8}; is invalid in C because there is no type specifier. – Vlad from Moscow Feb 07 '23 at 19:35
  • @VladfromMoscow You are correct, but it only generates a warning and the type defaults to an `int`. So, it's the "messy" equivalent of `static int arr[] = { ... };` – Craig Estey Feb 07 '23 at 19:38
  • 2
    [Undefined behavior](https://en.cppreference.com/w/cpp/language/ub). – Ivan Venkov Feb 07 '23 at 19:38
  • The former of these is plowing over the global process data region, the latter is plowing over automatic activation space (stack). Both invoke undefined behavior. – WhozCraig Feb 07 '23 at 19:42
  • The declaration `static arr[] = { … };` is valid in C90, but not in C99 or later versions of the standard. In C90, it is equivalent to `static int arr[] = { … };`. In C99 and later, the type does not default to `int` — you must specify it explicitly. GCC versions 4.x (or earlier) default to `-std=gnu90`; from 5.x onwards, they default to `-std=gnu11` (no versions of GCC default to `-std=gnu99`, though it can be specified on the command line). You should not be learning C90 — you should be learning C18 (which is, for most purposes, the same as C11). – Jonathan Leffler Feb 07 '23 at 19:54
  • 2
    Please see [No out of bounds error](https://stackoverflow.com/questions/9137157/no-out-of-bounds-error) Undefined behaviour doesn't guarantee anything. You only get the exception if you break something, or tread on something forbidden. – Weather Vane Feb 07 '23 at 19:56
  • 1
    The C language does not specify any circumstances in which a segmentation fault is triggered. From the perspective of the C language, therefore, it can only happen as a manifestation of undefined behavior (which your program indeed exhibits). Undefined behavior is undefined. C has no answer to questions about why it manifests in one way or another. – John Bollinger Feb 07 '23 at 19:57
  • The `static` keyword indicates the storage class (`auto`, `extern`, `register` are other [storage class specifiers](http://port70.net/~nsz/c/c11/n1570.html#6.7.1)). It means that the duration of the data in the array last for the lifetime of the program. In this code, it doesn't matter; in general, though, it means that the values in the array would preserve their values across function calls, rather than being initialized each time the function is called. All this is separate from the out of bounds behaviour caused by indexing to `50` when the array has only 8 elements. – Jonathan Leffler Feb 07 '23 at 19:57
  • In the first case, you didn't write outside of the segment or overwrite anything *important*. In the second case, you likely overwrote a return address or frame pointer. The behavior on writing past the end of an array is *undefined* - the language definition places no requirements on the compiler or operating environment to handle it in any particular way. A segfault is one possible outcome, but not the only one. – John Bode Feb 07 '23 at 20:01
  • 3
    The arrays are stored in different locations — 'stack' and 'data' sections. When you write beyond the bounds of the one allocated on the stack, you probably scribble over the stack, messing up return addresses, etc. When you write beyond the bounds of the one allocated in the data section, you probably scribble over other data — from the library etc — and don't wreck the stack, so the return completes OK. Scribbling beyond the end of the array yields undefined behaviour. Anything is allowed to happen; both crashing and not crashing are valid responses to UB. – Jonathan Leffler Feb 07 '23 at 20:01

0 Answers0