2

When I ran below program using gcc compiler, I end up in "Segmentation fault: 11", but when I ran the same at "https://www.onlinegdb.com/online_c_compiler", it is executing perfectly fine. I would like to know, why gcc is throwing segmentation fault here?

#include <stdio.h>

int main(){

    typedef int myArray[10];

    myArray x = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};//Equivalant to x[10]
    myArray y[2]; //equivalant to y[10][2]

    int counter = 0;

    for(int i = 0; i < 10; i++){
        for(int j = 0; j < 2; j++){
            //printf("%i %i\n", i, j);
            y[i][j] = counter++;
        }
    }

    printf("\n\nElements in array x are\n");
    for(int i = 0; i < 10; i++){
        printf("x[%i] = %i\n", i, x[i]);
    }

    printf("\n\nElements in array y are\n");

    for(int i = 0; i < 10; i++){
        for(int j = 0; j < 2; j++){
            printf("y[%i][%i] = %i\t", i, j, y[i][j]);
        }
        printf("\n");
    }

    return 0;
}

I am using gcc version 4.2.1. Operating System: MAC

$gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin18.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Werner Henze
  • 16,404
  • 12
  • 44
  • 69
Hari Krishna
  • 3,658
  • 1
  • 36
  • 57
  • can you use a debugger to see where it fails. Memory is contiguous so it doesn't matter the order of i and j with those arrays. – Jean-François Fabre Jan 23 '19 at 14:23
  • "I am using gcc version 4.2.1" isn't that a prehistoric version? gcc current version is 8. – Jean-François Fabre Jan 23 '19 at 14:23
  • 4
    You have a misconception about the layout of the `y` array. `myArray y[2];` is equivalent to `y[2][10]`, not what the code comment says. – Blastfurnace Jan 23 '19 at 14:26
  • yes, but that's not the issue, memory is contiguous on 2D arrays – Jean-François Fabre Jan 23 '19 at 14:30
  • @Blastfurnance, thanks for the correction. I would like to know, why the program running perfectly on 'https://www.onlinegdb.com/online_c_compiler'. Is it because, gcc is strict in boundary checks? – Hari Krishna Jan 23 '19 at 14:31
  • @Jean-FrançoisFabre I know, but I think it's useful to point out that the code comment and the loops show a fundamental misunderstanding. – Blastfurnace Jan 23 '19 at 14:32
  • have you tried to invert the boundaries on i and j and see if it works for you? out of bounds for an array is undefined behaviour. If the 2D arrays are contiguous it works but it's still not clean – Jean-François Fabre Jan 23 '19 at 14:32
  • 1
    @HariKrishna there is no boundary check in C. Accessing an array out of bounds results in _undefined behaviour_ (google that). Undefined behaviour includes "apparently working fine". – Jabberwocky Jan 23 '19 at 14:32
  • @Blastfurnace you're right. I started commenting exactly what you said, but I thought "that's not the issue" – Jean-François Fabre Jan 23 '19 at 14:32
  • 4
    @Jean-FrançoisFabre : the order of `i` and `j` does matter : `y[9][1]` has an address that is `(10 * 9 + 1) * sizeof(int)` beyond the start of the array, whereas the array only has room for 20 `int`s. – Sander De Dycker Jan 23 '19 at 14:35
  • Thanks for clarifying – Hari Krishna Jan 23 '19 at 14:42

1 Answers1

5

The comment here is wrong :

myArray y[2]; //equivalant to y[10][2]

y is actually defined as :

int y[2][10];

ie. y has 2 rows of 10 int's each.

When you then access y[i][j] with row index i ranging from 0 to 9 and column index j from 0 to 1, you end up accessing the array out of bounds whenever i * ROW_SIZE + j (or i * 10 + j) is larger than or equal to ROW_SIZE * ROW_CNT (or 10 * 2).

For example, y[9][1] tries to access the 2nd value on the 10th row. But there are only 2 rows in y.

Trying to access an array out of bounds has undefined behavior. Undefined behavior means anything at all can happen, including appearing to run fine or crashing.

To fix your code, define y as follows (so it matches the comment) :

int y[10][2];
Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40