0

would love for some help with understanding the difference between these two lines:

int(*p)[20] = (int(*)[20]) malloc(sizeof(int) * 20);
int* y = (int*)malloc(sizeof(int) * 20);

if I do:

int * tmp = p;
OR
int * tmp = y;

I get the address of the first element in the array/memory allocated.

Would love for some more thorough understanding of what the difference is and when would I use each one of them?

Addition to the question:

is this casting legal? please explain why and if it is legal, what is tmp equal to?:

int(*p)[20] = (int(*)[20]) malloc(sizeof(int) * 20);
int * tmp = (int*) p;

Thanks to anyone that contributes!

Sincerely,

Roe :)

Roe
  • 61
  • 1
  • 3
  • `p` is a pointer to a 2D array with 20 elements per row. You've allocated exactly one row. So you can access elements where the first index is 0, e.g. `p[0][0]`, `p[0][1]`, ... , `p[0][19]`. `y` is a pointer to a 1D array. You've allocated 20 elements for the array. – user3386109 Nov 17 '20 at 11:03
  • 1
    _... contributes to the discussion!_ StackOverflow isn't really the place for discussions, if that's what you're looking for. As far as when you would use each of these constructs, use the first if you need a 2D array, the second if you need a 1D array. – Mark Benningfield Nov 17 '20 at 11:10
  • 1
    @user3386109 `p` is **not** a pointer to a 2D array (the same way as `int *p1;` does not declare a pointer to a 1D array!). `p` is **a pointer to a 1D array of 20 ints.** Yes, there may be more of such arrays at `p+i`, but we don't generally know (much like we don't generally know whether there is another int at `p1+i`). In this case though we do know that there is exactly one such array (since only space for 20 ints was allocated) and `p+1` points to unallocated memory. – Peter - Reinstate Monica Nov 17 '20 at 11:20
  • Regarding the cast in the last snippet, it is not only legal, it is *required*. `tmp` and `p` are different pointer types, and you can’t assign one to the other without a cast. The exception to this rule is if one of the expressions has type `void *`. Since the `*alloc` functions return `void *`, you *don’t* need to cast the result. You can clean up your `malloc` calls like so - `int (*p)[20] = malloc( sizeof *p );` and `int *y = malloc( sizeof *y * 20 );`. `sizeof *p == sizeof (int [20])`. – John Bode Nov 17 '20 at 12:24

1 Answers1

0

int(*p)[20] is pointer to array of 20 integers

int* y is a pointer to an int.

when you increment p it will be incremented the sizeof(array of 20) integers ( on my system i see the difference of 80 bytes, since int is 4 bytes)

y is incremented just sizeof (int)

#include<stdio.h>
#include<stdlib.h>
int main() {
    int(*p)[20] = malloc(20*sizeof(int));
    int* y = malloc(sizeof(int) * 20);
    int (*pd)[20] =  p+1;
    int *yd = y+1;
    printf("p = %u and p+1 = %u \n", p, pd);
    printf("y = %p and y+1 = %p \n", y, yd);
    return 0;    
}
csavvy
  • 761
  • 4
  • 13