C - Pointers and Arrays - c

I've been trying to make a write to array method in C, but it does not seem to be returning what I expect.
How many numbers would you like to short?: 3
Checking for the i: 0: 1
Setting the number to temp 1
Checking for the i: 1: 2
Setting the number to temp 2
Checking for the i: 2: 3
Setting the number to temp 3
Setting the array2 to *array
0: 6487440
1: 0
2: 6480512
----------------------------------
Proces exited after 1.741 seconds with return value 3
And this is the code
int array_size;
void getArray(int *array[]);
void printArray(int array[]);
void main() {
printf("How many numbers would you like to short?: ");
scanf("%d", &array_size);
int input[array_size];
getArray(&input);
printArray(input);
}
void getArray(int *array[]) {
int i, temp;
int array2[array_size];
for(i = 0; i < array_size; i++) {
printf("Checking for the i: ");
printf("%d: ", i);
scanf("%d", &temp);
printf("Setting the number to temp %d\n", temp);
array2[i] = temp;
}
printf("Setting the array2 to *array\n");
*array = array2;
}
void printArray(int array[]) {
int i;
for(i = 0; i < array_size; i++) {
printf("%d: %d\n", i, array[i]);
}
}
I have also tried using
scanf("%d", &*array[i]);
but it does not work either.
Any ideas as to what I'm doing wrong?
Thanks in advance!

You are doing so many things wrong over here. First of all passing an array is not passing array will be simply
getArray(&input); --> getArray(input);.
The 1D-array when passed to a function decays into pointer - making it possible to retain any change made to the array (via pointer) in the called function.
void getArray(int *array) {
int i, temp;
for(i = 0; i < array_size; i++) {
printf("Checking for the i: ");
printf("%d: ", i);
scanf("%d", &array[i]);
}
}
This will do whatever you wanted to do. But earlier the assignment was wrong because the automatic variables are deallocated once the function reaches the }. So accessing it outside the function scope results in undefined behavior.
To give you a more elaborate idea, there are few things (Mostly the error message is being discussed).
If you compiled your code, then you would get some error. Now look at the error message.
error: cannot convert 'int (*)[array_size]' to 'int**' for argument '1' to 'void getArray(int**)'.
&input is nothing but int(*)[array_size]. It means it is a pointer to an array of array_size integers.
From looking at the error message you might think , but where from int** coming here in the argument of getArray()?
Well you were passing int* array[] (you declared that function will receive this as parameter) which means array is an array of int*-s. Now it decays into the pointer to it's first element.
Now wait, what is the element here? It's a pointer.
And what is pointer to pointer? Yes, it's int**.
Simply there is an error thrown - complaining that it can't convert.

Look at where you have decalred array2. As soon as you exit the scope of getArray(), the memory for it is deallocated. So when you try to access it later you end up with whatever is in memory at that moment.

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.

Why the values are not stored properly in pointers when assigning values at runtime(using scanf) in C language?

In C, When i assign values to pointers during compile time and print values, they are printing correct.
int main(void) {
int b;
int* a=&b;
for(int i=0;i<=5;i++){
*a=i;
a++;
}
a=&b;
for(int i=0;i<=5;i++){
printf("%d ", *(a+i));
}
return 0;
}
i am getting output as: 0 1 2 3 4 5
But when i assign values during runtime(using scanf) and print values, only the second value in pointer is replaced by last value of the pointer.
int main(void) {
int b;
int* a=&b;
for(int i=0;i<=5;i++){
int t;
scanf("%d", &t);
*a=t;
a++;
}
a=&b;
for(int i=0;i<=5;i++){
printf("%d ", *(a+i));
}
return 0;
}
Input: 0 1 2 3 4 5
Output: 0 5 2 3 4 5
However whatever the size of pointer, only second element is getting replaced by the last element in the pointer.
Can anyone clarify this.
This is undefined behavior. You're accessing a[0] to a[5], that's space for 6 integers. However, you only have space for one integer:
int b; // your one integer
int* a=&b;
If you increase a, it won't point to valid memory anymore. Instead of just having one int, try an array of 6 int instead:
int b[6];
int* a = b; // you can drop the "&" now as arrays decay to their pointers anyway
You might ask yourself "why did it work the first time and not the second time if its undefined behavior both times?". The problem with undefined behavior is that it is not guaranteed to do anything in particular. Working sometimes and the not working at other times is a common manifestation of UB. It could give you the result you expect and seem to work, and then suddenly fail when you try to demonstrate your program to a client.
On a side note, may I interest you in accessing arrays using this better readable syntax instead?
for (int i = 0; i <= 5; i++) {
a[i] = i;
}
for (int i = 0; i <= 5; i++) {
printf("%d ", a[i]);
}

My function not working 'name.exe has stopped working'

The program stops and I get a "merge.exe has stopped working" message. I simplefied everything but the problem seems to occur when calling the function...
#include <stdio.h>
#include <stdlib.h>
#define br 1000
int sort(int *list[],int broi);
int merge(int list1[],int list2[],int broi1,int broi2);
int main()
{
int i,n,m,a1[br],a2[br],a;
printf("gimme n: ");
scanf("%d",&n);
printf("gimme m: ");
scanf("%d",&m);
for(i=0;i<n;i++)
{
printf("gimme element %d ot list1: ",i+1);
scanf("%d",&a1[i]);
}
for(i=0;i<m;i++)
{
printf("gimme element %d ot list2: ",i+1);
scanf("%d",&a2[i]);
}
sort(&a1,n);
sort(&a2,m);
merge(a1,a2,n,m);
return 0;
}
int sort(int *list[],int broi)
{
int i,j,c;
for (i = 0; i < broi-1; i++)
{
for (j = 0; j < broi-i-1; j++)
{
if (*list[j] > *list[j+1])
{
c=*list[j];
*list[j]=*list[j+1];
*list[j+1]=c;
}
}
}
return 1;
}
int merge(int list1[],int list2[],int broi1,int broi2)
{
printf(" AAAAAA");
return 1;
}
In the sort() function is pretty self-explanatory and it even works!
But whatever I put in merge() it just won't won't work and it breaks the whole program.
In the sort() function is pretty self-explanatory and it even works! ? NO it won't work. Read the compiler warning by compiling with -Wall it says
reo.c:4:5: note: expected ‘int **’ but argument is of type ‘int *’ as you are passing address of a1 & catching with array of pointer. Instead just pass array name and catch with pointer.
Make function call looks like
sort(a1,n);/*just pass the array name */
sort(a2,m);
And definition of sort()
int sort(int *list,int broi){ /* take list is ptr variable */
int i,j,c;
for (i = 0; i < broi-1; i++) {
for (j = 0; j < broi-i-1; j++) {
if (list[j] > list[j+1]) {
c=list[j];
list[j]=list[j+1];
list[j+1]=c;
}
}
}
}
int *list[] makes list an array of pointers to int. In your main function &a1 (for example) create a pointer to an array of int, of type int (*)[1000]. int** (from the first) is not the same as int (*)[1000].
Simple solution? Don't pass a pointer to the array! This is very seldom needed.
And anyway because of operator precedence an expression like *list[i] is the same as *(list[i]), and if you have a pointer to an array you want (*list)[i]. So, many wrongs don't make a right.
Your compiler should have been shouting warnings about this to you.

Segmentation Fault when accessing global integer array

I am writing C code to take user parameters and build an integer array from them. I ask the user to provide the array length and each element's value.
Running the following code causes an error at the printArray() function call. Following the debugger into printArray(), the Segmentation Fault itself occurs at printf("%d", intArray[i])
NOTE: The array is correctly printed when I copy the printArray() code into main() instead of making a function call. This makes me think that I have an issue with global variables and/or pointers. I am still learning C, so your guidance is appreciated.
How can I fix this? See debugger output at the bottom for more info.
void printArray();
int arraySize;
int* intArray;
int main() {
printf("Enter array length:\n");
scanf("%d", &arraySize);
int* intArray = (int*) malloc(sizeof(int)*arraySize);
printf("Enter an integer value for each array element:\n");
for (int i = 0; i < arraySize; i++) {
printf("Enter element %d:\n", i);
scanf("%d", &intArray[i]);
}
printArray();
return 0;
}
void printArray() {
printf("[");
for (int i = 0; i < arraySize; i++) {
printf("%d", intArray[i]);
}
printf("]\n");
}
I think you have redeclared intArray variable in main()
int* intArray = (int*) malloc(sizeof(int)*arraySize);
by doing this, the scope of this variable is only in the main function and printArray() does not know about this definition. So printArray() tries to access intArray variable which you have declared globally(which does not have definition) and thus leading to segmentation fault.
So just give intArray = (int*) malloc(sizeof(int)*arraySize);

warning passing argument 1 of " " from incompatible pointer type enabled by default

randomAssign(int **grid, int size){
int m = rand()%size;
int n = rand()%size;
grid[m][n] = 1;
}
int main()
{
srand(time(NULL));
int i, j, size;
scanf("%d", &size);
int grid[size][size];
for(i=0; i<size; i++){
for(j=0; j<size; j++){
grid[i][j] = 0;
}
}
randomAssign(grid,size); //warning
return 0;
}
I am getting warning when i call the function. I tried all i can do but i couldn't find the mistake. Where is the mistake? Regards...
Arrays and pointers are different. An array is a series of contiguous elements of a particular type. A pointer is a small object that holds the address of another object.
Your function expects a pointer that points to another pointer. However you tried to supply an array to it. This can't possibly work.
One way to fix your code would be to make the function accept a pointer to an array (not a pointer to a pointer). This could be written:
void randomAssign(int size, int grid[size][size])
This is actually the same as having int (*grid)[size], the first size is redundant (see here for detail) however it serves some documentary purpose.

Resources