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
Related
The code breaks and doesn't run further after reaching the swap function, even though it works if I comment it out, and I don't see the problem of why it stops working.
#include <stdio.h>
#define size 10
void swap(int *max,int *minimum);//swaps maximum value location with minimum value location
void max_min(int arr[],int *max,int *min,int *locmin,int *locmax);
int main()
{
int grades[10]={40,52,77, 80, 85, 88, 90, 66,55,99};
int max=0,min=0,locmax,locmin;
max_min(grades,&max,&min,&locmin,&locmax);//Gets maximum-minimum values and their location
printf("Largest grade %d\n smallest grade %d\n",max,min);
swap(&grades[locmax],&grades[locmin]);// only swaps smallest-greatest value
}
void swap(int *max,int *minimum)
{
int temp=*max;
*max=*minimum;
*minimum=temp;
}
void max_min(int arr[],int *max,int *min,int *locmin,int *locmax)
{
int maxx,minx;
maxx=arr[0];
minx=arr[0];
for (int k = 0; k <size; k++)
{
for(int i=1; i<size; i++)
{
/* If current element is greater than max */
if(arr[i] > maxx)
{
maxx= arr[i];
*locmax=i;
}
/* If current element is smaller than min */
if(arr[i] < minx)
{
minx= arr[i];
*locmin=i;
}
}
}
*max=maxx;
*min=minx;
}
locmin and locmax are never initialized, neither by main nor by max_min. The result is they will contain whatever garbage was in memory at the time. If you're lucky that will be 0, but it could be anything. This can result in locmin or locmax being out out of bounds for the grades array. They're less then 0 or greater than 9. So grades[locmin] and grades[locmax] try to access memory your process does not own and results in a memory violation.
Looking at max_min(), notice that locmax and locmin are only assigned to conditionally. It may happen that they are never assigned to. Specifically if the first element of grades is also the smallest element locmin will never be assigned. It will contain whatever value it started with. If it was never initialized that will be garbage. That is what's happened.
To fix this, initialize them inside max_min. Don't make it the caller's responsibility, that is error prone. Also pass in size, don't use a global. And probably get rid of the max and min arguments, the caller can get them from locmin and locmax.
void max_min(int arr[], size_t size, int *locmin, int *locmax) {
// At the start, the first element is both the max and min.
int maxx = arr[0];
int minx = arr[0];
*locmax = 0; // <<<--- initialize to the first index
*locmim = 0; // <<<--- initialize to the first index
for (int k = 0; k < size; k++) {
for(int i=1; i< size; i++) {
// If current element is greater than max
if(arr[i] > maxx) {
maxx= arr[i];
*locmax=i;
}
// If current element is smaller than min
if(arr[i] < minx) {
minx= arr[i];
*locmin=i;
}
}
}
}
I had to give an initial value for both locmin,locmax of zero, then the program started working.
I don't know if this is something related to C but it's the first time where I have encountered such a problem.
#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));
For class I have to make a Selection Sort function recursively with no loops. I finally got it to compile with no errors, but now it just says "segmentation fault (core dumped)". I'm pretty new to C so please explain what this means. I'm assuming that there's a stack overflow, but I can't see where or how.
Here are my two functions involved in Selection Sort.
void CheckRemaining(int arr[], int minpos, int len, int j) {
if (j == len - 1) {
return;
}
if (arr[minpos] > arr[j]) {
minpos = j;
}
CheckRemaining(arr, minpos,len, j + 1); //j increments with each iteration
}
void SelectionSort(int arr[], int len) {
int i = 0;
int j;
int minpos;
minpos = i;
if (i == len - 2) {
return;
} else {
j = i;
CheckRemaining(arr, minpos,len, j);
swap(&arr[minpos], &arr[j]);
SelectionSort(&arr[i++], len); //The location in the array increments
}
}
int main() {
int i;
int len;
int arr[] = {5,7,3,2,9,4,10};
len = sizeof(arr)/sizeof(arr[0]);
SelectionSort(arr,len);
for ( i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
return 0;
}
Am I missing something big here?
You are most likely correct that you have a stack overflow, because the recursion will never end.
The problem is that you use the local variable i in the condition to terminate the recursion, but you forget that local variables are local for each call. Every time the SelectionSort is called, there will be a new i variable initialized to zero, so the recursion will never end.
SelectionSort(&arr[i++], len);
I think, it should not work for this code. The recursion will never end. Every time you are calling to SelectionSort() and initializing i with 0. So i will never be len-2. Each time this function is getting a different i.
int i=0;
You defined i as a local scope variable, meaning that every time is called, i=0 is taking effect, preventing you from ever having any i greater then 0, thus this condition:
if (i==len-2)
will never be true. Hence, you get an infinite loop.
By the way, to answer to you about the segfault, when you have a segmentation fault, it means that you wanna reach a "forbidden" memory area, for example (usual error in beginning) when you didn't malloc'd a string/tab and your loop's index is "too far" you want to access to a "forbidden" area then it segfault.
I hope you have spent beautiful Christmas holidays. I am studying for an exam and I have a problem with my project in ANSI C. My code works but not always, it's strange because for some input values it works for other not. I have two arrays, A and B, that must be different in size and I have to write a function that do the mathematical union of the two arrays in another array. If there are elements of the same value I have to insert in the new array only one. I write all the code (I also post a question here because I had some problems with the union) but it does not work always. Gcc compile and I execute but it's not correct. I debugged with gdb and it said
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400d1c in unionearraycrescente (a=0x7fffffffdd50, indice_m=4,
b=0x7fff00000005, indice_n=5, minimo=6, indiceMinimo=22)
at array.c:152
152 if(b[i]==c[j])
And this is the code near the problem
int arrayun(int a[], int index_m, int b[], int index_n, int minimum, int indexMinimum)
{
int i=0;
int j=0;
int found;
int lenc=0;
int c[lenc];
for(i=0;i<index_m;i++){
found = 0;
for(j=0; j<i && !found;j++)
if(a[i]==c[j])
found = 1;
if(!found)
c[lenc++] = a[i];
}
for(i=0;i<index_n;i++){
found=0;
for(j=0;j<i && !found;j++)
{
if(b[i]==c[j]) //debug gbd problem - segfault
found = 1;
}
if(!found)
c[lenc++] = b[i];
}
I am Italian so the comments are in my language, if you have any problems I will translate the comments. I want only to resolve this memory error. Thank you.
I follow some of your advices and in that part of code it works, I changed all the variables with index_m and I don't receive segfault but after the union I use the selection sort to sort in ascending order and it return me not the right values but in the first position negative values.
int arrayun (int a[], int index_m, int b[], int index_n, int minimum, int indexMinimum)
{
int i=0;
int j=0;
int found;
int lenc;
int c[index_m];
for(i=0;i<index_m;i++){
found = 0;
for(j=0; j<i && !found;j++)
if(a[i]==c[j])
found = 1; //setta trovato = 1
if(!found)
c[index_m++] = a[i];
}
for(i=0;i<index_n;i++){ //index_m or index_n?
found=0;
for(j=0;j<i && !found;j++)
{
if(b[i]==c[j]) //debug gbd problem - segfault - SOLVED but
found = 1;
}
if(!found)
c[index_m++] = b[i];
}
for (i=0; i<index_m-1;i++)
{
minimum=c[i];
indexMinimum=i;
for (j=i+1;j<index_m; j++)
{
if (c[j]<minimum)
{
minimum=c[j];
indiexMinimum=j;
}
}
c[indexMinimum]=c[i];
c[i]=minimum;
}
for(i=0;i<index_m;i++)
printf("Element %d\n",c[i]);
return c[index_m]; //I think here it's wrong
}
int c[lenc]; means in your program it is c[0]
and you are allocating ZERO Memory for the array.
And if you try for b[i]==c[i] where i>=0 means its a segmentation fault only.
Instead you can initialize like,
c[index_m];
int lenc=0;
int c[lenc];
this is array of 0 length.and in loop you are trying to access c[1],c[2]... etc.
To cure this problem you can pass length of the bigger array
int unionearraycrescente (int a[], int index_m, int b[], int index_n,int len, int minimum, int indexMinimum)
and you can then initialize like
int c[len];
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.