Segmentation Fault while initializing array in C - c

I am a very beginner in C. I went through the existing questions but could not understand because they involved strings and characters. Here is my little part of my code:
#define grid 32
int main (void)
{
int NU, NV, NP;
NU=(grid-1)*grid;
NV=grid*(grid-1);
NP=grid*grid;
double u[NU], uc[NU];
double v[NV], vc[NV];
double p[NP], pc[NP];
//Initialization
// Initializing u
for (i=0; i<(grid-1); i++)
{
for (j=0; j<(grid); j++)
{
int k=j*grid+i;
if (j==(grid-1))
{
u[k]=1.0;
}
else if (j==(grid-2) && i>0 && i<(grid-2))
{
u[k]=1.0;
}
else
{
u[k]=0.0;
}
}
}
// Initializing v
for (j=0; j<(grid-1); j++)
{
for (i=0; i<grid; i++)
{
int k=j*grid+i;
v[k]=0.0;
}
}
// Initializing p
for (j=0; j<grid; j++)
{
for (i=0; i<grid; i++)
{
int k=j*grid+i;
p[k]=1.0;
}
}
I am trying to initialize these arrays but instead getting segmentation fault.
Kindly help me with this.

This line is the problem:
int k=j*grid+i;
Its taking your array index out of bounds. When you access u[k] then you get a seg fault. Also, there is no need to use 2 loops to initialize a single dimensional array unless there is a specific logic you are trying to implement here which i am not aware of.

You defined
NU=(grid-1)*grid;
NV=grid*(grid-1);
NP=grid*grid;
Now let's see how far you are accesing the array elements in the loop.
for (i=0; i<(grid-1); i++)
{
for (j=0; j<(grid); j++)
{
int k=j*grid+i; // so in the max case k = (grid-1)*grid+grid-2 = grid*grid+2
... // and it is larger than NU so it will be accessing wrong memory
// memory region
}
}
Follow the same anlysis to make sure other array initialization does not exceed the boundary.

The only reason array initialization can result in a SEGFALT is by reading or writing to an element which does not exist.
The most common way to accomplish this is by using an index beyond the bounds of the array. In C, the lowest element is index 0 (zero) and the highest is N-1 where N is the number of elements declared for the array.
int array [5000];
array [-1] = 0; /* BAD */
array [5000] = 0; /* BAD */
Both of these are invalid accesses. They might SEGFAULT. They might change another variable's value. They might seem to do nothing. Or they might seem to work.

Related

Reverse bubble sort (biggest to the left) doesn't seem to work [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I want to sort 12 integers using a "reverse bubble sort" (We call it "the drowning axe sort", whatever). My function looks good to me but something goes wrong.
Error: having typed my 12 random numbers I don't get the result printed, instead my compiler stops and does not proceed any further.
Can anyone help?
Code:
#include<math.h>
#include<math.h>
void array_clean(int a[11]) //just an array cleaner
{
for(int i=0; i<12; i++)
{
a[i] = a[i]&&0; // smth && 0 = 0 anyway
}
}
void axe_sort(int a[11]) //drowning-axe sort function
{
int place = 0;
for(int i=0; i<12; i++)
{
for(int j=0; j<12; j++)
{
if(a[j]<a[j+1])
place=a[j];
a[j] = a[j+1];
a[j+1] = place;
}
}
}
int main(void)
{
int array[11]; //declaring an integer array;
array_clean(& array[11]); // giving user-filed array to a cleaner function
printf("Enter 12 random integers you'd like to sort: ");
for(int m=0; m<12; m++)
{
scanf("%d", &array[m]); //letting user to fill an array
}
axe_sort(&array[11]); //sorting an array via our axe_sort function
for(int m=0; m<12; m++)
{
printf("%d", array[m]); //printing the sorted array
}
return 0;
}
Your array int array[11]; isn't doing what you think it is. That declares an array of 11 ints, indexed from 0 to 10 inclusive. There is no array[11] therefore trying to access this will lead to undefined behavior.
You've got the correct form of your for loop, it'll correctly iterate over 12 members of the array, numbered 0 to 11 inclusive. However you need to declare the array as int array[12]; to get it big enough to work.
Also, you're passing the array to the two functions using &array[11]. You just need to say array and it'll pass in the array correctly. What you're doing will cause the two functions to write over random memory, which definitely won't help.
Try fixing these and see what changes.
First of all, You should include stdio.h header file in order to use printf() and scanf()
You are dealing with 12 integers. Then Why did you declare an array of 11 integers???
int array[11]; //declaring an integer array; <-------- change the size to 12 from 11
The purpose of the array_clean(); is to initialize each number with 0. You can simply put 0 instead of a[i]&&0;
Here you are passing the address of 12th element.
array_clean(&array[11]); //<---------------------
You should pass the address of the base element(1st).
You can do this by two ways.
array_clean(&array[0]);
Or,
array_clean(array);
When an array is used as a value, its name represents the address of the first element.
And finally, please check your bubble sort logic.
for(int j=0; j<12; j++)
{
if(a[j]<a[j+1])
{place=a[j]; //<-----curly braces missing in the body of if
a[j] = a[j+1]; //<----error
a[j+1] = place;
}
}
For j=11, your code will try to access 12th index and that will give you a segmentation fault. Enclose the body of if with curly braces.
Here is the modified code
#include<math.h>
#include<stdio.h> // <---------- include this header file
void array_clean(int a[12]) //just an array cleaner
{
for(int i=0; i<12; i++)
{
a[i] = 0; // smth && 0 = 0 anyway
}
}
void axe_sort(int a[12]) //drowning-axe sort function
{
int i,j;
for(i=0; i<11; i++)
{
for(j=0; j<11-i; j++) //<-------- see the logic carefully
{
if(a[j] < a[j+1]) //<-----put curly braces
{int place=a[j];
a[j] = a[j+1];
a[j+1] = place;}
}
}
}
int main(void)
{
int array[12]; //declaring an integer array;
array_clean(&array[0]); // <---------------- pass the base address
printf("Enter 12 random integers you'd like to sort: ");
for(int m=0; m<12; m++)
{
scanf("%d", &array[m]); //letting user to fill an array
}
axe_sort(&array[0]); // <---------------- pass the base address
for(int m=0; m<12; m++)
{
printf("%d ", array[m]); //printing the sorted array
}
return 0;
}
I think you forgot to include the stdio.h library in your code

what is the segmentation fault in this program

#include<stdio.h>
#include <stdlib.h>
int main()
{
int n,small=0,large=0,s,l,temp;
printf("this should work");
scanf("%d",&n);
// printf("%d",n);//
int a[n];
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
/* for(int i=0;i<n;i++)
printf("%d",a[i]);*/
small=a[0];
large=a[n-1];
for(int i=0;i<n;i++)
{
if(a[i]<small && i!=0)
{
small=a[i];
s=i;
}
if(a[i]>large && i!=n-1)
{
large=a[i];
l=i;
}
}
temp=a[s];
a[s]=a[l];
a[l]=a[s];
for(int i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}
This is a simple program to swap the largest and smallest number in an array and print the new array.
When I tried to run this program I got a segmentation fault.
Usually, a segmentation fault occurs when we try to access an out of bound memory location.
So I added printf statements to find out where the error is.
But none print statements were executed. what is the error here ?
One problem is that you don't actually set s and l to anything unless you find an element that is smaller/larger than the current one.
That means (for example), if the first element is the smallest, s will be set to some arbitrary value and trying to index the array with it could be problematic.
To fix that, where to set small and large, you should also set:
s = 0;
l = n - 1;
In addition, your swap code is wrong and should be:
temp = a[s];
a[s] = a[l];
a[l] = temp;
You should initialize s and l to some value because when the if condition does not works their values will remain uninitialized garbage values. Hence, a[l] or a[s] will not work, since these indexes are undefined values. That is why you will get segmentation fault because you are accessing an undefined area of an array.
So, use random values within array range like s=0,l=0 to initialize the variables or you can add some flags to check if the conditions are working.
if (l != 0 && s != 0) {
temp=a[s];
a[s]=a[l];
a[l]=a[s];
}
Also, I think you are swapping the values so in the last line a[l]=temp instead of a[l]=a[s].
ideone link
You cannot declare an array based on a dynamic size, unless the compiler supports it and even then it is generally not portable.
int a[n]
you actually need to use malloc or calloc.
int *a;
a = (int *)malloc(n * sizeof(int)); or a = (int *)calloc(n, sizeof(int));

Can you use double brackets in a nested for loop?

What I mean by my question is that if I have a nested for loop like
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; i++)
{
printf("%d\n"___);
}
}
What would I put in the blank? Would [i][j] be illegal if I declared an array already?
I am not sure what exactly you are stuck on based on your question so I made a minimal C program with comments
I declared an int array who's first and second dimension are at least 10 because you iterate both i and j from 0 to 9 (inclusive). This is to avoid out of bounds problems while iterating
The array's elements are not initialized in the program. It is possible that this program will print all zeros when you run it. It is also possible that it prints other values that happened to be in memory (because the array values are not initialized)
Last I declared i and j outside the for loop just in case this was the problem you were facing
#include <stdio.h>
int main(int argc, char** argv) {
// Declare an array
// Note that both dimensions are at least 10
// Also note that none of the values are initialized here
int myArray[10][10];
// Both i and j are declared here rather than in the for loop
// This is to avoid the following potential error:
// error: 'for' loop initial declarations are only allowed in C99 or C11 mode
int i, j;
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
// Note that the values this prints are uninitialized
printf("%d\n", myArray[i][j]);
}
}
return 0;
}
Your question was really unclear. But from what I understand is you have some 2-d array, and you want to print contents of array.
You must have arrary already defined as int arr[10][10], then you can use,
printf("%d\n", arr[i][j]);

Concatenating two 2d char arrays

I wrote a small program to combine two 2d arrays. Here is the code:
#define MAX 7
int main(void) {
int i, j;
char *array1[] = {"Welt,", "bist", "du"};
char *array2[] = {"noch", "zu", "retten?"};
char final[MAX][MAX];
for(i = 0; i < 3; i++) {
// initialize ith names element with first name
strcpy(final[i], array1[i]);
}
for(j = 0; j < 3; j++) {
// concatenate the last name to the firstname+space string
strcat(final[i], array2[j]);
}
for (i = 0; i != 6; i++) {
printf("%s", final[i]);
}
return EXIT_SUCCESS;
}
I get really strange output like:
Welt,bistbistdunochzuretten?uretten?en?
while what I want is this:
Welt,bistdunochzuretten
As you can see it is not completely wrong. There should not be a space between the words.
How can I fix my code?
The problems were that in the second for you were doing strcat(final[3], array2[j]);, because i was 3 at that point and in the final for you were trying to print from final[0] to final[5], when you only had defined final[0] to final[3] (where on final[0] to final[2] you had the names, and in final[3] you had all the last names concatenated which also exceeded the limit of characters), and without printing them in a new line it was hard to tell which string was what.
Try this.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 7
int main(void) {
int i,j;
char *array1[] = {"Welt","bist","du"};
char *array2[] = {"noch","zu","retten?"};
char final[MAX][MAX];
for(i=0;i<3;i++)
strcpy(final[i], array1[i]); //To initialize ith names element with first name
for(j=0;j<3;j++)
strcat(final[j],array2[j]); //Concatanate the last name to the firstname+ space string
for (i = 0; i < 3; i++)
printf("%s\n", final[i]);
return EXIT_SUCCESS;
}
There are several problems with your code:
The constant MAX is not large enough for your data. The string "retten?" contains seven characters plus one terminating byte. As such, MAX must be at least 8, otherwise you get undefined behavior.
Your second loop contains uses the wrong index into final[i]. See point 3. for corrected versions.
The use of strcat() is wrong, you should be using strcpy() just like in the first loop. Together with point 2., your second loop should either look like this:
for(j = 0; j < 3; i++, j++) { //add increment for i
strcpy(final[i], array2[j]);
}
or like this:
for(j = 0; j < 3; j++) {
strcpy(final[3 + j], array2[j]); //derive the index from j
}
Regarding Point 1, I always advise against using any compile time constants like MAX. My experience is that these are just bugs that are waiting to strike. Someday, someone will have a use case that exceeds the limit, and your program goes boom. I always allocate buffers to fit the strings that I need to store, leaving the available RAM as the only limit to my code. To this end, functions like strdup() and asprintf() are extremely handy because they already do the allocation for me.
Regarding Point 2, you should try to declare all your loop variables right inside the initialization statement. Like so:
for(int i = 0; i < 3; i++) {
// initialize ith names element with first name
strcpy(final[i], array1[i]);
}
That way you don't run the danger of inadvertently using the loop variable after the loop / forgetting the initialization, etc. because your compiler will complain about the unknown variable.

segfault when iterating over 2d array

I am trying to do a simple function which prints an array of a defined size. However, after the function prints the array, a seg fault occurs. This seg fault only occurs when boardSIZE is defined as equal to 19 or larger. Anything less then 19, and no segmentation fault occurs. Can anyone explain why this is, and/or suggest how I can perform a similar task of defining a global variable larger than 20 here without getting a seg fault?
#include <stdio.h>
#define boardSIZE 40
void printBoard(char [][boardSIZE]);
int main()
{
char board[boardSIZE][boardSIZE];
printBoard(board);
}
void printBoard(char board[boardSIZE][boardSIZE])
{
int i,j;
for (i=0;i<=boardSIZE;i++){
for (j=0;j<=boardSIZE;j++){
board[i][j]='X';
printf("%c",board[i][j]);
}
printf("\n");
}
}
Don't use <= in your loops. Use <. For an array of size n, valid indexes go from 0 to n-1. Thus, your loop is accessing out-of-bound positions.
Change your printBoard() function to:
void printBoard(char board[boardSIZE][boardSIZE])
{
int i,j;
for (i=0;i<boardSIZE;i++){
for (j=0;j<boardSIZE;j++){
board[i][j]='X';
printf("%c",board[i][j]);
}
printf("\n");
}
}
you blow the array bounds.
you allocated boardSIZE, this means the max index that is available is boardSIZE - 1 because the first index is 0 not 1. so change the <= to < in both for loops and the seg fault will resolve!
void printBoard(char board[boardSIZE][boardSIZE]) {
int i,j;
for (i = 0; i < boardSIZE; i++){
for (j = 0; j < boardSIZE; j++){
board[i][j] = 'X';
printf("%c",board[i][j]);
}
printf("\n");
}
I suggest you edit your title to something more suitable as this doesn't have anything to do with global variables

Resources