0

Trying to understand pointers as a beginner in C- I've got this struct:

    typedef struct {
        int size;           // dimension of array
        int **arr; // pointer to heap allocated array
    } someStruct;

So I use malloc to generate this struct, and an array, and initialize all the values to zero-

someStruct *m = (someStruct*)malloc(sizeof(someStruct));
m->size = n;
m->arr = (int**)malloc(n * sizeof(int));
// initialize array
for (int i = 0; i < n; i++) {
    *(m->arr + i) = (int*)malloc(n * sizeof(int));
    // set value to 0
    for (int j = 0; j < n; j++) {
        *(*(m->arr + i) + j) = 0;
    }
}

After this I basically continue to access the array in later stages using the same kind of pointer logic-

for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        int num =  *(*(m->arr + i) + j);
        printf("num: %d\n", num);
    }
}

Here's the problem- when I try to use this method of access, I'm clearly not getting the right answer- my print output look like this:

num: -2043774080
num: 22031
num: 0
num: 0
...
num: 0
num: 0

Here's the really weird part- this seeming bug of the 'weird' random numbers only comes when I'm creating and accessing an array of size 5-

I've come to believe that the whole

*(*(m->arr + i) + j)

method of access must be wrong- any help on this would be really useful. Thanks in advance, I apologize if this was already answered, my searching was unable to find it.

3
  • 2
    malloc(n * sizeof(int)) allocates storage for n integer values, but for the outer level you are using this as if it's storage for n pointer values. If sizeof(int) < sizeof(int*) on your system, you're in for a bad time. Now, please stop using pointer dereferencing for array-like access. *(*(m->arr + i) + j); is equivalent to m->arr[i][j] -- one of these is readable, and one is not. Commented Feb 23, 2022 at 1:14
  • @paddy so would the problem be in the access code or when I typecast to int* during the assignment? Commented Feb 23, 2022 at 1:35
  • m->arr = (int**)malloc(n * sizeof(int)); is a problem. Avoid guessing the type: Use m->arr = malloc(sizeof m->arr[0] * n);. Commented Feb 23, 2022 at 1:46

1 Answer 1

1

You should give complete code, but I think I was able to figure out your intent. You have one glaring problem, and many style issues. Here is what I think your code should look like:

typedef struct {
    int size;           // dimension of array
    int **arr; // pointer to heap allocated array
} MagicSquare;

  :
  :

// no need to dynamically allocate this, it is small
MagicSquare m;
m.size = n;
m.arr = malloc(n * sizeof(int*));  // note it is sizeof(int*), not (int)

// initialize array
for (int i = 0; i < n; i++) {
    m.arr[i] = malloc(n * sizeof(int));
    // set value to 0
    for (int j = 0; j < n; j++) {
        m.arr[i][j] = 0;
    }
}

  :
  :

for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        printf("num: %d\n", m.arr[i][j]);
    }
}

Note that if you want to initialize the allocated memory to zero, you should just use calloc, which does this initialization for you:

// initialize array
for (int i = 0; i < n; i++) {
    m.arr[i] = calloc(n,sizeof(int));
}
Sign up to request clarification or add additional context in comments.

4 Comments

m.arr = malloc(n * sizeof m.arr[0]); avoids type mis-match better than trying to synchronize the pointer and its type.
True, @ReinstateMonica... or m.arr = malloc(n * sizeof *m.arr); Similarly, we could use m.arr[i] = calloc(n,sizeof *m.arr[i]);
Hey, thanks for the answer, the fix works- I'm just trying to understand this- a lot of online tutorials seem to like to use this whole typecast thing of calling m->arr = (int*)malloc(n * sizeof(int)); is this method of doing it completely invalid? I also tried to format the question better, apologize for that mess.
In C, it's advisable to omit the cast. The typecast is required for the code to be compiled with a C++ compiler. Of course, if you're using C++ then using malloc at all is not generally recommended. Unfortunately the quality of "online tutorials" is quite a mixed bag.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.