Array pointer in C program - c

Here is a C program in textbook, it asks a 3*5 2D array from users and prints the third line.
I am confused with int* p[5]. Why here needs to have [5], I think just int* p is OK. It can repeatedly add and point to the next memory space in the int array. And can anyone explain how pointer works in this program?
#include <stdio.h>
int main(void){
int a[3][5];
int i,j;
int *p[5];
p = &a[0];
printf("Please input:\n");
for(i = 0; i < 3; i++){
for(j = 0; j<5;j++){
scanf("%d\n",(*(p+i))+j);
}
}
p = &a[2];
printf("the third line is:\n");
for(j = 0; j<5; j++){
printf("%5d", *((*p)+j));
}
printf("\n");
}

int *p[5];
is an array of five pointers to int.
What you want is a pointer to an array of five ints
int (*p)[5];
because &a[0] is the address of the 1st element of a which is an int[5].
The compiler should have clearly issued at least a warning on this, if not an error, which would be expected.
More on this here: C pointer to array/array of pointers disambiguation

Related

C: how to give 2D Array to a function

I want to pass a 2D array already filled with chars to a different method to do something with it.
Background: I am trying to implement GameOfLife. And I have already successfully implement the gameboard with a random amount of living cells. But now I want to pass the board(Array) to a different method to continue working with it. How to do so?
//wow das wird hurenshon
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void spielStarten(int x, int amountOfLiving){
char feld[x][x];
for(int i = 0; i < x; i++){
for(int j = 0; j < x; j++){
feld[i][j] = 'o';
}
}
for(int i = 0; i < amountOfLiving; i++){
int a = (rand()%x);
int b = (rand()%x);
feld[a][b] = 'x';
}
printf("Gameboard: \n");
for(int i = 0; i < x; i++){
for(int j = 0; j < x; j++){
printf("%c ", feld[i][j]);
}
printf("\n");
}
spielRun(feld);
}
void spielRun(char feld[][]){
int neighbCount;
char feldNew[][] = feld[][];
for(int i = 0; i < x; i++) {
for(int j = 0; j < x; j++) {
checkForNeighbours(feld[x][y]);
// in progress
}
}
}
int main(int argc, char* argv[]){
srand(time(NULL));
int x = 16;
if(argc < 2 || argc > 3){
printf("2. Argument eine Zahl fuer Feldgroesse eingeben\n");
printf("1. Argument eine Zahl 0-10 fuer ungefähre prozentuale Belegung mit lebenden
Zellen eingeben \n");
return 0;
}
if(argv[2] != NULL){
x = atoi(argv[2]);
}
int i;
i = atoi(argv[1]);
i = (x^2)*(0,1*i);
spielStarten (x,i);
return 0;
}
In the last line of the Method "Spiel starten" i want to give the array to the next Method "spielRun".
Edit: thanks to an other user I found this struture:
void printarray( char (*array)[50], int SIZE )
But it doesn't work for me since I can´t hardcode the number, because the arraysize depends on a user input.
thanks!
The difficulty here is that the size of your array is not known statically (once upon a time, your code would even not compile for the same reason).
That, combined with the fact that 2D-arrays are not arrays of 1D arrays (contrarily to what happen when you malloc a int ** and then every int * in it), and so it doesn't make sense not to specify the size when passing it to a function.
When using arrays of arrays (technically, pointers to a bunch of pointers to ints), like this
void f(int **a){
printf("%d %d %d\n", a[0][0], a[1][0], a[0][1]);
}
int main(){
int **t=malloc(10*sizeof(int *));
for(int i=0; i<10; i++) t[i]=malloc(20*sizeof(int));
f(t);
}
That code is useless, it prints only unitialized values. But point is, f understands what values it is supposed to print. Pointers arithmetics tells it what a[1] is, and then what a[1][0] is.
But if this 2D-array is not pointers to pointers, but real arrays, like this
void f(int a[][20]){
printf("%d %d %d\n", a[0][0], a[1][0], a[0][1]);
}
int main(){
int t[10][20];
f(t);
}
Then, it is essential that the called function knows the size (or at least all sizes, but for the first dimension) of the array. Because it is not pointers to pointers. It is an area of 200 ints. The compiler needs to know the shape to deduce that t[5][3] is the 5×20+3=103th int at address t.
So, that is roughly what is (better) explained in the link that was given in comments: you need to specify the size.
Like I did here.
Now, in your case, it is more complicated, because you don't know (statically) the size.
So three methods. You could switch to pointers to pointers. You could cast your array into a char * and then do the index computation yourself (x*i+j). Or with modern enough C, you can just pass the size, and then use it, even in parameters, declaration
void f(int x, int a[][x]){
printf("%d %d %d\n", a[0][0], a[1][0], a[0][1]);
}
int main(){
int t[10][20];
f(t);
}
Anyway, from an applicative point of view (or just to avoid segfault) you need to know the size. So you would have had to pass it. So why not pass it as first parameter (Note that the function in which you have this size problem, spielRun, does refers to a x, which it doesn't know. So, passing the size x would have been your next problem anyway)
So, spielRun could look like this (not commenting in other errors it contains)
void spielRun(int x, char feld[][x]){
int neighbCount;
char feldNew[][] = feld[][]; // Other error
for(int i = 0; i < x; i++) {
for(int j = 0; j < x; j++) {
checkForNeighbours(feld[i][j]); // Corrected one here
// in progress
}
}
}
And then calls to this spielRun could be
spielRun(x, feld);
Note that I address only the passing of array of size x here. There are plenty of other errors, and, anyway, it is obviously not a finished code. For example, you can't neither declare a double array char newFeld[][] = oldFeld[][]; nor affect it that way. You need to explicitly copy that yourself, and to specify size (which you can do, if you pass it).
I am also pretty sure that i = (x^2)*(0,1*i); does not remotely what you expect it to do.

Array of pointers whose elements point to another array of pointers

What I need very precisely is an array A[10] and each of its element pointing to the respective element of array B[10] whose each element store its index.
Hence, A[1] points to B[1] and B[1] has value of 1.
So, when I call *A[1] or *B[1], I get 1.
I know it can be super easy if the array B[10] is not an array of pointers but of integers but I need this for another purpose.
This is what I did but segmentation fault was offered.
#include <stdio.h>
int main() {
int *A[10];
int *B[10];
for(int i=0; i<10; i++) {
A[i] = B[i];
*B[i] = i;
printf("\n%d %d",*A[i],*B[i]);
}
}
By the way, I am not very proficient in pointers.
Your commented code :
int main() {
int *A[10]; // an array of 10 pointers, each of them pointing nowhere
int *B[10]; // an array of 10 pointers, each of them pointing nowhere
// now each array a and b contain 10 uninitialized pointers,
// they contain ideterminate values and they point nowhere
for(int i=0; i<10; i++) {
A[i] = B[i]; // copy an uninitialized pointer
// this usually works but it's pointless
*B[i] = i; // you assign i to the int pointed by *B[i]
// but as *B[i] points nowhere you end up with a segfault
printf("\n%d %d",*A[i],*B[i]); // you never get here because the previous
// line terminates the program with a segfault,
// but you'd get a segfault here too for
// the same reason
}
}
Your program is basically equivalent to this:
int main() {
int *a; // a is not initialized, it points nowhere
*a = 1; // probably you'll get a segfault here
}
Accessing the thing pointed by a pointer is called dereferencing the pointer. Dereferencing an uninitialized pointer results in undefined behaviour (google that term), most likely you'll get a seg fault.
I'm not sure what you're trying to achieve, but you probably want something like this:
#include <stdio.h>
int main() {
int* A[10];
int B[10];
for (int i = 0; i < 10; i++) {
A[i] = &B[i];
B[i] = i;
printf("%d %d\n", *A[i], B[i]);
}
}

dereference a pointer to a pointer casted from array pointer

Learning C and this confusing me:
#include <stdio.h>
int main(){
int m[5][5];
int count = 0;
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
m[i][j] = count++;
}
}
int **p = m;
int (*k)[5] = m;
printf("%p\t%p\t%p", *p, *k, *m);
return 0;
}
that's what has been printed:
0x100000000 0x7ffff1fc9d70 0x7ffff1fc9d70
I'm really confused why dereference *p is 0x100000000, shouldn't it be 0x7ffff1fc9d70?
You’re thinking that m is of type int **, right?
It’s not. If you had done this, it would be:
int *m[5];
That make an array of five pointers to int, so m would be pointer to pointer to int.
However, if you do this:
int m[5][5];
You get enough space for 25 ints, which the compiler will access as a 5x5 two-dimensional array. p points to the beginning of that array. Dereference it, and the compiler reads the beginning of that array and interprets it as a pointer to int. Change the numbers you’re filling it with, and you’ll get different pseudo-pointers.

What is the purpose of using (*ptr)[5] instead of *ptr? [duplicate]

This question already has answers here:
Difference between "pointer to int" and "pointer to array of ints"
(8 answers)
Closed 4 years ago.
I read about (*ptr)[5] that it can point to a 5-element integer array. What this means?
It can be used when you want to go through a 2-d or a higher dimensional array.
For example you have this 2-d array:
int a[3][4] = {
1,2,3,4,
5,6,7,8,
9,0,1,6
};
A normal *ptr will go through each of the elements in the array.
If this array's base address is : 1000. Then the next address it will go to on increment would be 1002, 1004, 1006. Taking sizeof(int) => 2.
What (*ptr)[5] would do is to jump to the next 5th element and then point to it.
In the example taken above, if I want to jump on the very starting of each 1-d array in it, I would simply use (*q)[4] and jump to the next 4th element and just not the very next one.
So if you want to display the elements of this array you can do this in two ways:
Using normal *ptr
void display(int *q, int row, int col){
int i, j;
for(i=0; i<row; i++){
for(j=0; j<col; j++){
printf("%d ", *(q + i*col + j));
}
printf("\n");
}
}
Using (*ptr)[4]
void show(int (*q)[4], int r, int col){
int i, j, *p;
for(i=0; i<r; i++){
p = q+i;
for(j=0; j<col; j++){
printf("%d ", *(p+j));
}
printf("\n");
}
}
int (*q)[5] means that q is a pointer to an array of 5 integers. To understand better let us use this pointer to an array of 5 integers.
void main()
{
int a[][5] = {
1,2,3,4,5,
6,7,8,9,10,
11,12,13,14,15
};
int *p;
int (*q)[5];
p = *a;
printf("%d %d\n",p,q);
p++;
q++;
printf("%d %d\n",p,q);
}
Output:
65500 65500
65502 65510
To begin with, both p and q contain the same address 65500. However, on incrementing p it points to an array of 5 integers.Hence on incrementing p it points to the next integer,
whereas q starts pointing to the next 1-D array of 5 integers. Pointer to the array is very useful while passing a 2D array to functions.

Dereferencing a Two Dimensional Array In C

I'm having some difficulties understanding two dimensional arrays in C.
Let's look at this example:
#include <stdio.h>
void foo(int arr[2][3]) {
printf("%d", *arr);
}
int main() {
int arr[2][3] = { {10, 20, 30},
{40, 50, 60}
};
foo(arr);
return 0;
}
I have a few questions:
What is the value of arr? Is it the address of arr[0][0]?
If arr is the address of arr[0][0], then why the line:
printf("%d", *arr);doesn't print the value 10?
Each time I run it, I get a strange number. what is the meaning of this number?
Thanks :)
In answer to your questions:
Used in an expression, the value of arr is a pointer to its first element. Since it's an array of arrays, the pointer to its first element is &arr[0]. This value has an unusual type, "pointer to array of 3 ints".
Because arr is not the address of arr[0][0].
This is a crazy situation, hard to understand and hard to explain. In brief: since arr is a pointer to an array, *arr is that array. But when you try to pass it to printf, the compiler turns around and generates a pointer to the array's first element again. I suspect that pointer value differs because your compiler and OS are putting main (and therefore arr) in a different place on the stack each time. (And then there's the additional problem that since we're talking about pointers, it doesn't necessarily work to print them %d, especially if your machine has 32-bit ints and 64-bit pointers.)
My advice to you is not to worry about why the incorrect code printed changing values. Rather, please just print the array correctly, with code like this:
int i, j;
for(i = 0; i < 2; i++) {
for(j = 0; j < 3; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
It is possible by doing like this:
#include <stdio.h>
int main()
{
int arr[2][2] = {{2,3},{5,6}};
for (int i = 0; i < 2; i++) {
for (int j = 0;j < 2; j++) {
printf("%d\n" , *(&arr[i][j]));
}
}
}

Resources