Segmentation Fault when accessing global integer array - c

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);

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.

Segmentation fault in passing multidimensional arrays to functions in C

We saw passing arrays to functions using pointers in my intro. to C class, and I'm trying to learn how to pass multidimensional arrays on my own. I tried writing a function to assign the values of the entries of a matrix onto a local array, but I get a segmentation fault. I was hoping someone could explain why this happens and how to fix it. I'm using the terminal on macOS Sierra. Thanks in advance. My code is below:
#include <stdio.h>
#include <stdlib.h>
void fillMatrix();
int main(void){
int rows, cols;
printf("\nEnter the number of columns:\n");
scanf("%d", &cols);
printf("\nEnter the number of rows:\n");
scanf("%d", &rows);
int matrix[rows][cols];
fillMatrix(&matrix[rows][cols], rows, cols);
for (int i = 0; i < rows; ++i){
for (int j = 0; j < (cols - 1); ++j){
printf("%d ", matrix[i][j]);
} printf("%d\n", matrix[i][(cols -1)]);
}
return 0;
}
void fillMatrix( int *matrix, int rows, int cols ){
for (int i = 0; i < rows; ++i){
for (int j = 0; j < cols; ++j){
printf("\nPlease enter the A(%d,%d) entry:\n", i, j);
scanf("%d", &*(matrix + (i*cols) + j));
}
}
return;
}
Given the declaration
int matrix[rows][cols];
This code is wrong:
fillMatrix(&matrix[rows][cols], rows, cols);
The address of &matrix[rows][cols] is past the end of the matrix.
The first element of the matrix is &matrix[0][0], and the last element of the matrix is &matrix[rows-1][cols-1].
Also, this declaration
void fillMatrix();
will cause problems with this defintion:
void fillMatrix( int *matrix, int rows, int cols ){
...
They need to match. Right now, because of the void fillMatrix() declaration up top, arguments get passed to the function via default argument promotion, but because the definition has explicit arguments, the function itself expects the arguments to be passed as int * or int. You're probably not having problems with that as the defaults for those arguments are likely the same as those arguments, but function definitions and declarations generally must match exactly.
I haven't examined your code for other issues.
In C when you are declaring an array you need to specify its size at the time of compilation. When you decelerate the array in line
int matrix[rows][cols];
You actually initialise its size with rubbish values. In case of my compiler it was initialised with size of [0][0]. In order to achieve what you want you need to do one of two things:
Specify explicitly what is the size of the array before compilation
Dynamically allocate space for the array

Segmentation fault when trying to add elements of an array

I'm trying to create a function that returns as its result the sum of the elements in the array. When I try to run the program, I get a segmentation fault. Could someone please point me in the right direction? Thank you!
int arraySum (int array[], int numberOfElements) {
int result = 0;
for (int i = 0; i < numberOfElements; i++)
{
result += array[i];
}
return result;
}
int main (void) {
int numberOfElements;
int *array = NULL;
printf("How many elements would you like in your array: ");
scanf("%i", &numberOfElements);
printf("\nPlease list the values of the elements in the array: ");
for (int i = 0; i < numberOfElements; i++)
{
scanf("%i", &array[i]);
}
int result = arraySum(array, numberOfElements);
return result;
}
The problem you have is, that in C you need to manually allocate the memory if you are using a pointer instead of say a fixed-size array.
This is usually done by calling malloc, which will return a void-pointer (void*), which you need to cast to the desired type (in your case (int*)) before assigning it.
It is also important to note, that, when using malloc, you need to specify the amount of Bytes you want to allocate. This means that you can't just call it with the number of integers you want to store inside, but rather have to multiply that number with the amount of Bytes that one integer occupies (which depends on the Hardware and Operating System you use, hence you should use sizeof(int) for that purpose, which evaluates to that size at compile time).
I modified your code with a working example of how it could be done:
#include <stdio.h>
#include <stdlib.h>
int arraySum (int array[], int numberOfElements) {
int result = 0;
int i;
for (i = 0; i < numberOfElements; i++) {
result += array[i];
}
return result;
}
int main(int argc, char **argv) {
int numberOfElements;
int *array = NULL;
printf("How many elements would you like in your array: ");
scanf("%i", &numberOfElements);
array = (int*) malloc(numberOfElements * sizeof(int));
printf("\nPlease list the values of the elements in the array: ");
int i;
for (i = 0; i < numberOfElements; i++) {
scanf("%i", &array[i]);
}
int result = arraySum(array, numberOfElements);
printf("\n\nThe result is: %d\n", result);
return 0;
}
You are also trying to return the result in your main function, but the return value of main in C is used to signal whether your program terminated without errors (signalled by a return value of 0) or didn't encounter any issues (any value other than 0).
You need to allocate memory. It is not enough to just declare a pointer. You do it like this: array=malloc(numberOfElements*sizeof(*array));
Also, although it is possible to return result from the main function, you should not do that. The return value from main is usually used for error checking. Change the end of your program to
printf("Sum: %d\n", result);
return 0;
Returning 0 usually means that no error occurred.

C - Pointers and Arrays

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.

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