0

while running the code below in C (visual studio 2019), I get Access violation error in the "SetArr" function

the program stops and exits with this message.

any help will be appreciated

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

void SetArr(int** arr, int rowNum, int colNum);
void zeros(int** arr, int rowNum, int colNum);

int **arr1, **arr2;

int i, j, input,output;

int main() {
    zeros(arr1, 2, 3);
    SetArr(arr1, 2, 3);

}

void zeros(int** arr, int rowNum, int colNum) {
    arr = (int**)malloc(sizeof(int*) * rowNum);
    for (i = 0; i < rowNum; i++) {
        arr[i] = (int*)malloc(sizeof(int) * colNum);
    }
}

void SetArr(int **arr, int rowNum, int colNum) {
    for (i = 0; i < rowNum; i++) {
        for (j = 0; j < colNum; j++) {
            scanf_s("%d", &input);
            arr1[i][j] = input;
        }
    }`
}
asaf
  • 1
  • 1
  • 2
    Read this: https://stackoverflow.com/questions/766893/how-do-i-modify-a-pointer-that-has-been-passed-into-a-function-in-c – Jabberwocky Apr 29 '21 at 14:09

2 Answers2

3

C uses pass-by-value for all function argument passing.

Just like if you want to modify a variable passed as an argument in the called function and have that change reflect in the caller, you pass address of that variable, same way, if you want to modify a pointer, you need to pass the address of that pointer.

Call you function like

 zeros(&arr1, 2, 3);

and in the function, use it like

void zeros(int*** arr, int rowNum, int colNum) {
    *arr = malloc(sizeof(int*) * rowNum);
    for (i = 0; i < rowNum; i++) {
        (*arr)[i] = malloc(sizeof(int) * colNum);
    }
}
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Hmmm, If I have `int a[1]` and call `foo(a)`, and not "pass address of that variable," `&a` as suggested, The value of `a` (the array's contents) can certainly change. From the caller's point-of-view, acts like pass by reference. IOWs, C does not have so much "pass-by-value" restriction always as much as "received by value" given the hidden array to address of the first element conversion. – chux - Reinstate Monica Apr 29 '21 at 17:18
  • @chux-ReinstateMonica Does it not like in most cases, including when passing as function argument, a type with array gets converted to pointer to the first element of the array? Also, as array is a collection of a particular member object type, the address of the first element is the address of the array variable itself. So, without the explicit use of unary `&` operator, are we not still passing the address of the variable? – Sourav Ghosh Apr 29 '21 at 18:44
  • 1
    The point is that `foo(a)` with `int a[1]`, from the caller's point of view, is a pass by reference. The underlying mechanics do convert the `a` to `&a[0]`, yet that is an implementation detail. In any case, minor point and good answer. – chux - Reinstate Monica Apr 29 '21 at 19:06
1

You're passing arr1 to the zeros function by value. So when you modify it in the function, the change isn't reflected in the calling function. This means that when you call SetArr you're reading an uninitialized pointer.

Change zeros to return the pointer that it allocates:

int **zeros(int rowNum, int colNum) {
    int arr = malloc(sizeof(int*) * rowNum);
    for (i = 0; i < rowNum; i++) {
        arr[i] = malloc(sizeof(int) * colNum);
    }
}

And assign the return value to arr1:

arr1 = zeros(2, 3);
dbush
  • 205,898
  • 23
  • 218
  • 273