0
int main()
{
    int r;
    scanf("%d", &r);
    int **arr = (int *)malloc(r * r * sizeof(int));
    *(*(arr + r) + r);

    for (int i = 1; i <= r; i++)
    {
        for (int j = 1; j <= r; j++)
        {
            printf("Enter element %d.%d: \n", i,j);
            scanf("%d", &arr[i-1][j-1]);
        }

    }
    getch();
}

so this recently happened, basically what I want is to append matrix elements to 2d array, but it says

'Exception thrown at 0x0F1B97AE (ucrtbased.dll) in Matrix.exe: 0xC0000005: Access violation writing location 0xCDCDCDCD'

don`t know what to do :( help please

dbush
  • 205,898
  • 23
  • 218
  • 273
Yuriy
  • 71
  • 5
  • 2
    What's up with this line? `*(*(arr + r) + r);` Anyway, you need to use pointer arithmetic to access the array elements as it has been allocated at runtime. – Blaze Oct 22 '18 at 13:50
  • [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – Lundin Oct 22 '18 at 13:53

4 Answers4

2

You're using a malloc'ed block of memory as a C multi-dimensional array. Instead, you need to use a single set of square brackets.

Instead of arr[i-1][j-1], you need something like arr[i * r + j].

I'm surprised that most compilers would accept this by default because you use an int * to initialize and int **.

Thomas Jager
  • 4,836
  • 2
  • 16
  • 30
  • it works ! but throws another exception when I try to print out elements `printf("%d", arr[i][j])` do I have to access them with something like `arr[i * r + j]` ? – Yuriy Oct 22 '18 at 14:13
1

The problem is that you don't allocate or create a "two-dimensional" array. Your memory allocation allocates one array of r * r elements.

This single array can't be used as an array of arrays.

The usual solution to create a dynamic array of arrays is to create a jagged array:

int **arr = malloc(r * sizeof(int *));
for (unsigned i = 0; i < r; ++i)
{
    arr[i] = malloc(r * sizeof(int));
}

You can use a large single array in a "two-dimensional" way, but you need to use some other arithmetic to access the elements of it:

arr[i * r + j]

[Note that the above requires zero-based indexes i and j]

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1
int **arr = (int *)malloc(r * r * sizeof(int));

You can't create a 2D array with a single allocation like that, at least not one you can access with a int **. What you have instead is space for r * r, objects of type int which can be accessed via a int * and some additional arithmetic.

When you later do this:

*(*(arr + r) + r);

The first dereference is fine, since arr points to an allocated buffer. The second one is not, however, because you read an uninitialized value from that allocated buffer and attempt to use to as a valid address. This invokes undefined behavior which in this cause results in a crash.

You need to allocate space for an array of int *, they for each of those allocate an array of int:

int **arr = malloc(r * sizeof(int *));
for (int i=0; i<r; i++) {
    arr[i] = malloc(r * sizeof(int));
}
dbush
  • 205,898
  • 23
  • 218
  • 273
  • Of course you can create it with a single allocation, that's the proper and most correct way. But you will have to drop the `int**` thing, since it can't point at a 2D array. – Lundin Oct 22 '18 at 13:54
1

Just forget all about this int** nonsense and allocate a 2D array instead:

#include <stdio.h>
#include <stdlib.h>

int main (void)
{
    int r;
    scanf("%d", &r);
    int (*arr)[r] = malloc( sizeof(int[r][r]) );

    for (int i = 0; i<r; i++)
    {
        for (int j = 0; j<r; j++)
        {
            arr[i][j] = 1; // some sort of input here
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    free(arr);
}

Output example with input 5:

5
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

For this to work, you need a standard-compliant C compiler from this millennium.

More information: Correctly allocating multi-dimensional arrays.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • doesn`t work, it says that 'r' has to be a constant value – Yuriy Oct 22 '18 at 14:07
  • @СтепанБандера It works just fine. See the sentence "For this to work, you need a standard-compliant C compiler from this millennium." Apparently you are using a dinosaur compiler. – Lundin Oct 22 '18 at 14:11
  • sorry for not seeing, I`m using Visual Studio 2017, is it bad ? – Yuriy Oct 22 '18 at 14:14
  • @СтепанБандера Yeah it is bad. In C mode, it is a dinosaur compiler from the early 1990s. Microsoft has pretty much dropped their support for C and VS is best off if regarded as a C++ only compiler. – Lundin Oct 22 '18 at 14:33
  • what should I use ? – Yuriy Oct 22 '18 at 14:42
  • @СтепанБандера gcc, clang, icc, whatever compiler that's updated. Codeblocks with the default gcc/Mingw installation under Windows is both free and beginner-friendly. – Lundin Oct 22 '18 at 14:49
  • thanks for advice, I will definitely try it, but my professor at uni only wants us to use VS 2017... can I change compiler in VS ? – Yuriy Oct 22 '18 at 17:17
  • @СтепанБандера You can set it to "C mode" somehow, but then it barely follows the 30 years old C90 standard. – Lundin Oct 22 '18 at 18:13