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.
Related
I've been working on a recursive version of selection sort. MaxInd worked fine with one iteration of SelectionSort, but once I made SelectionSort recursive, MaxInd started to produce incorrect values after the first iteration of SelectionSort, which caused my code to swap incorrect values. I'm not sure why it's doing this.
#include <stdio.h>
int MaxInd(int arr[], int i, int len, int max, int index){
if (arr[i]>max){
max=arr[i];
index=i;
}
if(i==len)
return index;
index = MaxInd(arr,i+1,len,max,index);
return index;
}
void SelectionSort(int arr[], int len){
int index=0; int max=0; int i=0; int temp=0; int num=0;
if(len<0){
for(int j=0; j<6; j++)
printf("array=%d\n",arr[j]);
return;
}
num = MaxInd(arr, i, len, max, index);
if(len>0){
temp=arr[len-1];
arr[len-1]=arr[num];
arr[num]=temp;
for(int j=0; j<6; j++)
printf("%d ",arr[j]);
printf("\n");
}
return SelectionSort(arr,len-1);
}
int main(void){
int arr[6] = {1,4,3,7,9,2};
int len=sizeof(arr)/sizeof(arr[0]);
SelectionSort(arr, len);
}
The correct way to handle the return statement would be to write it like this
return SelectionSort(arr,len-1);
You are supposed to return an int from the function - but you didn't put any return statement - and then again you tried to use it's value. This is undefined behavior.
That will make sure - after it hits the bottom of recursive calls it will return the value returned correctly so that successive parent functions get it. Don't forget that return just terminates the execution of a function and returns control to the calling function.
Also note that - sorting functions are generally made to not return anything (void return type)- but in this case after all that of work, you are returning something that is nothing other than 0. So it leaves us with the question - is it the correct value you are returning?
Also your maxInd function would return 6 in the first call - and it is wrong. It can't be a valid index in a length 6 array in c as array indexing is 0-based on c. Otherwise you are invoking Undefined Behavior on your code. Correct order would be to - first check whether it (the index) is out of bound, if it is, then on that case return the index otherwise go looking for it via making successive calls.
if(i == len)
return index;
if (arr[i] > max){
max = arr[i];
index = i;
}
Just correcting the code - gives a correct result.(Removing undefined behavior from your code) (By correct result I mean it sorts the array but you are least concerned about it). Here.
Also as Jonathan Leffler mentioned, the indentation in your code was misleading. The compiler generated message is [-Werror=misleading-indentation] and you should treat it accordingly. You can see how proper indentation makes this error go away.
#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));
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
I'm trying to find the sum of all positive numbers in an array. So far, I have come up with this;
int largest_sum_sequence(int list, int size)
{
int sum = 0, *index = 0;
for (index < size; index = size; index++)
{
if (list[index] > 0)
{
sum = sum + list[index];
}
}
printf("%d", sum);
return sum;
}
My program keeps crashing. I'm pretty sure it has something to do with index. Whenever I use list[index] it says that I need to use a pointer for index, but I don't know how to do that properly. Help is appreciated!
You do not want index to be a pointer, and your for loop is incorrect. Try:
int sum = 0, index = 0;
for (; index < size; index++)
The compiler tells you actually exactly what to do.
First of all you need an array or a pointer as a parameter, like
int largest_sum_sequence(int *list, int size)
{
....
}
or
int largest_sum_sequence(int list[], int size)
{
....
}
where the latter might be easier to read.
The second thing is, you don't want to iterate with a pointer through the list, but more with a simple integer.
so you declare
int sum = 0, index = 0;
The for() loop isn't quite correct either. Instead of initializing something, you test if index < size and discard the result. This is syntactically correct, but doesn't make sense.
The first part in the for-statement is executed before the loop starts, but doesn't influence the starting itself. It is meant for initializing the loop variable (index in this case). The second part is the termination condition. The loop terminates if the condition evaluates to false. The last part of the loop is for incrementing (or decrementing, more abstract, changing) the loop variable.
Having said this, it is halfway obvious it should look like:
for (index = 0; index < size; ++index) {
....
}
Assuming your list isn't very long (such that the sum could exceed 2^{31} - 1), the rest is correct. Although I'd add an \n to the printf() pattern.
Where is the list coming from? Can't answer that from your code, but you've room for mistakes here too :-)
Function argument doesn't except an array.
Quick function I wrote.
int getSums(int myArray[], int size)
{
int total = 0;
int index = size;
for ( int i = 0; i < index; i++)
{
if (myArray[i] > 0)
total += myArray[i];
}
return ( total );
};
I am writing a program in which I have to manage an array of strings. Throughout the program, the strings are systematically removed/modified until only a single string remains.
I remove the strings when they are no longer needed using this function:
void remove_element(char **array, int index, int array_length)
{
int i;
for(i = index; i < array_length - 1; i++){
array[i] = array[i + 1];
}
free(array[array_length]);
}
Once I am totally done with the array, I use this function to ensure all the strings are free'd:
void free_fragments(char **frags){
int i = 0;
while((frags[i] != NULL) && sizeof(frags[i] != 0)){
free(frags[i]);
i++;
}
free(frags);
}
Yet, when I do this, valgrind gives me an "Invalid free() / delete / delete[] / realloc()" error, specifically complaining about the "free(frags[i])" line in free_fragments.
I understand that free_fragments seems kind of redundant, simply because theoretically I can call remove_element on each element until there is one remaining and then remove_element that as well, but when I try to do that, I still get a Invalid free() error, but this time complaining about remove_element. If I don't call free_fragments when I am done with the array, I get a memory leak.
My understanding of pointers is pretty beginner, so please help me debug this and improve my understanding!
The problem is that while you do free(array[array_length]);, you do not NULL it out, so in free_fragments you still think it is a valid pointer.
Come to think of it, you seem to free, the wrong entry, too... This should work:
void remove_element(char **array, int index, int array_length)
{
int i;
free(array[index]);
for(i = index; i < array_length - 1; i++){
array[i] = array[i + 1];
}
array[array_length-1] = NULL;
}
Assuming that index refers to index of string in 2d array which you want to free, I believe that there is a memory leak in your program. Wouldn't the memory address of string to be freed be lost in the first iteration: array[index] = array[index + 1].
Also you are going outside array's boundary in the last statement and freeing entirely something else. Basically there is a memory leak and you should free the string before overwriting its address with neighbouring strings as defined in #LaszloLadanyi's solution.
void remove_element(char **array, int index, int array_length)
{
int i;
for(i = index; i < array_length - 1; i++){
array[i] = array[i + 1];
}
/* Array indexes in C are in the range [0 - length-1]. Here
you are going outside array boundaries.
*/
free(array[array_length]);
}
I think you need to modify you codes to
void remove_element(char **array, int index, int array_length)
{
int i;
for(i = index; i < array_length - 1; i++){
array[i] = array[i + 1]; //I don't understand what's purpose here
}
free_fragments(array); //array[array_length] is a invalid pointer, out of range
}