Getting sigabrt error in heapsort program - c++

I am getting sigabrt error as given below for the given heapsort program. I am new to programming so I apologize for silly mistakes.
error : Abort signal from abort(3) (SIGABRT)
The major parts of the code are as follows
heapify - a program to make a heap out of the given array
heapsort - a function which sorts the array according to a heap and saves the result in the array
main - the driver function
#include <iostream>
#include <math.h>
using namespace std;
void swapper (int first, int second) {
int temp;
temp = second;
second = first;
first = temp;
}
void heapify (int a[], int size) {
for(int i = 0; i < (size/2) ; i++) {
int left = 2*i;
int right = 2*i + 1;
if (a[i] < a[left]) {
swap(a[i], a[left]);
}
else if (a[i] < a[right]) {
swap(a[i],a[right]);
}
}
}
void heapsort(int a[], int size){
int treesize = size;
int i = size;
heapify(a,size);
while (treesize > 0) {
cout << " \t " << a[i];
swap(a[i],a[0]);
i --;
treesize--;
heapify(a, treesize);
}
cout <<"\n";
for(int i = 0; i < size; i++) {
cout <<"\t"<<a[i];
}
}
int main() {
// your code goes here
int a[] = {10,1,2,11,4,57,12,13,44,14,6,7,9,8,15,16,17,98};
int arrsize= sizeof(a)/(sizeof(a[0]));
int pos;
int ele = 7;
heapsort(a,arrsize);
for (int i = 0; i < arrsize; i++){
cout <<"\n "<<a[i];
cout<<"\n"<<arrsize;
}
return 0;
}

I'm not sure about the correctness of the rest of the program, but the reason why you're getting the exception is because you're accessing memory out of bounds. You call heapsort with the array size like this:
heapsort(a, arrsize);
And then you set treesize and i to that size:
int treesize = size;
int i = size;
And then in those lines:
cout << " \t " << a[i];
swap(a[i], a[0]);
i is still equal to arraysize. But it can at most be arraysize-1. This causes undefined behavior when you print a[i], and even worse, undefined behavior in the following line that modifies values outside of the array. On my machine, the former prints rubbish values and the latter causes stack corruption. Instead, you should set those values like this:
int treesize = size-1;
int i = size-1;
This fixes the print and the exception.

Related

Array sum not printing in recursive function

I wrote a recursive function that returns the sum of the array when called. This is my code:
#include <iostream>
struct array {
int A[10];
int size;
int length;
};
void displayArray(struct array arr) {
std::cout << "the elements are :-" << std:: endl << '\t';
for (int i = 0; i < arr.length; i++) {
std::cout << arr.A[i] << ',';
}
std::cout << std::endl;
}
int i = 0;
int sum(int* a, int length) {
// Size of an int element.
int j = 4;
if (i < length) {
return a[i+1] + sum((a + j), length);
}
else {
return 0;
}
}
int main()
{
struct array arr = {{1,2,3,4,5,6,7}, 10, 7};
int* p;
std::cout<< sum(&arr.A[0],arr.length );
}
However, it is not returning anything and also, I ran it on an online compiler. It is not showing any error or warning, but it's not showing any output either.
well in this
int i = 0;
int sum(int* a, int length) {
int j = 4;
if (i < length) {
//std::cout << a[i];
return a[i] + sum((a + j), length);
}
}
your exit condition is i >= length, but you never change i so this will keep recursing till you run out of stack space. Since this is a very strange function (I mean why is j = 4) I cant suggest a solution, only why it doesnt work at present
here is the error on my dev box
Unhandled exception at 0x00007FF711A9297E in ConsoleApplication2.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x0000003E526B3FA8).
You are running in an endless loop because of your if condition never reaching an end.
Besides this, the global i and the local j are both superflous.
Maybe it would be easier to use your length to access the array and as an end marker and decrease it with each call of sum
int sum(int* a, int length){
if (--length >= 0)
return a[length] + sum(a, length);
else
return 0;
}
by the way, I would recommend using
`std::array <int, 10> a= {1,2,3,4,5,6,7};'
instead of your struct including int A[10];
this gives you out of bounds checking, iterators for your collection, no need for C pointer algorithmics, ...

C++ error variable declared void when passing array into function

I'm trying to refresh myself in C++ before my college starts again and I ran into some problems. I'm using a bubblesort function given by my professor and I'm struggling to run it in my int main. The function parameters is bubblesort(int *a, int length), so I used bubblesort(a, sizeof(a)/sizeof(*a) ).
The compiler shows an error ' a ' is declared void. I tried searching up for an answer if I made a mistake but I couldn't catch my error. If you understand why I am getting this error can you please explain in detail what I'm missing or doing wrong.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
void bubblesort(int *a, int length)
{
int i, temp, finished = 0;
while(!finished)
{
finished = 1;
for( i = 0; i< length-1; i++)
{
if(a[i] > a[i+1])
{
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
finished = 0;
}
}
}
}
int main()
{
int a[] = {5,1,7,9,4,3};
for (int i = 0;i < sizeof(a)/sizeof(*a);i++){ cout << a[i]; }
cout << endl;
void bubblesort(a, sizeof(a)/sizeof(*a));
for (int i = 0;i < sizeof(a)/sizeof(*a);i++){ cout << a[i]; }
}
You don't need return type in function call.
Remove void from the line
void bubblesort(a, sizeof(a)/sizeof(*a));
and make it
bubblesort(a, sizeof(a)/sizeof(*a));
You can't specify the return type of a function when making a function call, so you need:
bubblesort(a, sizeof(a)/sizeof(*a)); // no void at the beginning
However, you have a fixed-size array, so the call could also simply be:
bubblesort(a, std::size(a));
Also, this loop:
for (int i = 0;i < sizeof(a)/sizeof(*a);i++){ cout << a[i]; }
can be rewritten like this:
for (int elem : a)
cout << elem;

Removing cout statement causing value change of a variable

In the following code, when I'm removing cout statement (line after //******)then it is causing a change in the value of "i".
I used TDM-GCC 4.9.2 32 bit release and TDM-GCC 5.1.0 compilers.
I ran this code on codechef and there it runs fine and cout statement is not affecting the value of "i".
#include<iostream>
using namespace std;
int subset(int [], int);
int main()
{
int size,i,ans;
cout<<"size of array : ";
cin>>size;
int arr[size];
for(i = 0 ; i<size;i++)
{
cin>>arr[i];
}
ans = subset(arr,size);
cout<<"ans = "<<ans;
return 0;
}
int subset(int arr[], int size)
{
int i,j, tsum=0, completed=0;
for(i = 0 ;i<size;i++)
tsum = tsum + arr[i];
int carr[tsum+1],temp;
for(i=0;i<size;i++)
{
temp = arr[i];
carr[temp] = 1;
for(j=i+1;j<size;j++)
{
temp = temp + arr[j];
carr[temp] = 1;
}
}
for(i=1;i<=tsum;i++)
{
if(carr[i]!=1)
{
//************************************
cout<<"i : "<<i<<endl;
break;
}
}
return i;
}
Sample input :
size of array : 3
1
2
5
sample output without cout statement :
ans = 6
sample output having cout statement :
i : 4
ans = 4
Actual answere is 4 for the input.
The main problem seems to be that carr is uninitialized.
It is declared as
int carr[tsum+1]
with no initializer.
Later on some elements are set, but always to 1:
carr[temp] = 1;
In the last loop carr is examined:
if(carr[i]!=1)
This condition makes no sense. Either carr[i] has been set, then it is guaranteed to be 1, or it is uninitialized, in which case this comparison has undefined behavior.
Note that variable-length arrays are not standard C++.
To solve the problems as stated by Some Programmer Dude and melpomene, i.e. Variable-length arrays are not standard C++ and carr is uninitialized. Use c++ vectors and initialize them correctly. That would look something like this:
#include <iostream>
#include <vector>
using namespace std;
int subset(const std::vector<int>, const int);
int main()
{
int size, i, ans;
cout << "size of array : ";
cin >> size;
std::vector<int> arr(size);
for (i = 0; i < size; i++)
{
cin >> arr[i];
}
ans = subset(arr, size);
cout << "ans = " << ans;
return 0;
}
int subset(const std::vector<int> arr, const int size)
{
int i, j, tsum = 0, completed = 0;
for (i = 0; i < size; i++)
tsum = tsum + arr[i];
std::vector<int> carr(tsum + 1, 0);
int temp;
for (i = 0; i < size; i++)
{
temp = arr[i];
carr[temp] = 1;
for (j = i + 1; j < size; j++)
{
temp = temp + arr[j];
carr[temp] = 1;
}
}
for (i = 1; i <= tsum; i++)
{
if (carr[i] != 1)
{
//************************************
cout << "i : " << i << endl;
break;
}
}
return i;
}

How do i find the maximum number in an Array using a function

In my c++ class, i'm supposed to use this " int mymaximum(int a[], int numberOfElements); " function to find the maximum number in an Array. The function should return the largest in this array.
This is the code I have so far without the function I need to use. Thanks in advance and sorry about the messy code, still learning.
#include <iostream>
using namespace std;
int main() {
int Array[] = {23,2,90,53,38};
int mymaximum = 0;
for(int i = 0; i < 5; i++){
if(Array[i] > mymaximum){
mymaximum = Array[i];
}
}
cout << "The Max is: " << mymaximum << "\n";
return 0;
}
Just wrap around the logic to find maximum in a function. Like this:
int mymaximum(int a[], int numberOfElements)
{
// moved code from main() to here
int mymaximum = 0;
for(int i = 0; i < numberOfElements; i++)
{
if(a[i] > mymaximum)
{
mymaximum = a[i];
}
}
return mymaximum;
}
Aso, in order to support negative numbers, modify your logic like this:
int mymaximum(int a[], int numberOfElements)
{
// moved code from main() to here
int mymaximum = a[0];
for(int i = 1; i < numberOfElements; i++)
{
if(a[i] > mymaximum)
{
mymaximum = a[i];
}
}
return mymaximum;
}
Note that now I initialize maximum with the first entry in the array!
In main() call your method like this:
int main() {
int Array[] = {23,2,90,53,38};
cout << "The Max is: " << mymaximum(Array, sizeof(Array) / sizeof(Array[0])) << "\n";
return 0;
}
I'll show the overall structure without solving the homework for you:
#include <iostream>
using namespace std;
int mymaximum(int a[], int numberOfElements) {
int ret = 0;
// compute the maximum and store in `ret'
...
return ret;
}
int main() {
int Array[] = {23,2,90,53,38};
cout << "The Max is: " << mymaximum(Array, sizeof(Array) / sizeof(Array[0])) << "\n";
return 0;
}
In case you're wondering, sizeof(Array) / sizeof(Array[0]) computes the size of the array so that you don't have to hard-code it here.
Just move your logic into the desired function as follows:
int mymaximum(int Array[], int numberOfElements)
{
int mymaximum = 0;
for(int i = 0; i < numberOfelements; i++){
if(Array[i] > mymaximum){
mymaximum = Array[i];
}
}
return mymaximum;
}
Put that above int main(), then inside main() replace the removed code with:
int mymaximum = ::mymaximum(Array, 5);
(The :: wouldn't be needed if either the local variable or the function had different names).
You should then apply the suggestion in sasha's comment to use [0] as the initial guess at a maximum.
Replace your for loop structure with this:
int max(0);
max = mymaximum(Array, 5);
In the function mymaximum use this code:
int max(a[0]);
for(auto i(1); i < numberOfElements; ++i)
if(a[i] > max)
max = a[i];
return max;

FirstChance Exception StackOverFlow Merge Sort Shell Sort Bubble Sort

Hey guys I'm working on some sorts and am trying to implement a bubble sort, a merge sort, and a shell sort. I use an outdated technique but I was wondering if you guys could let me know why I keep getting the following error:
First-chance exception at 0x01135EF7 in sortApplication2.exe: 0xC00000FD: Stack overflow (parameters: 0x00000000, 0x00542000).
Unhandled exception at 0x01135EF7 in sortApplication2.exe: 0xC00000FD: Stack overflow (parameters: 0x00000000, 0x00542000).
I am using Visual Studio 2012 if that plays any part. My code is in three different files so I'll post each separately.
My header file:
#pragma once
class sort
{
public:
sort();
void random1(int array[]);
void random2(int array[]);
void random3(int array[]);
void bubbleSort(int array[], int length);
/*void merge(int *input, int p, int r);
void merge_sort(int *input, int p, int r);*/
void shellSort(int array[], int length);
};
My class implementation file:
#include "sort.h"
#include <time.h>
#include <iostream>
using namespace std;
sort::sort()
{}
void sort::random1(int array[])
{
// Seed the random-number generator with current time so that
// the numbers will be different every time the program runs.
for(int i = 0; i < 25; i++)
{
srand ((unsigned) time(NULL));
int n = rand(); //generates a random number
array[i] = n; //places it into the array
}
}
void sort::random2(int array[])
{
// Seed the random-number generator with current time so that
// the numbers will be different every time the program runs.
for(int i = 0; i < 10000; i++)
{
srand ((unsigned) time(NULL));
int n = rand(); //generates a random number
array[i] = n; //places it into the array
}
}
void sort::random3(int array[])
{
// Seed the random-number generator with current time so that
// the numbers will be different every time the program runs.
for(int i = 0; i < 100000; i++)
{
srand ((unsigned) time(NULL));
int n = rand(); //generates a random number
array[i] = n; //places it into the array
}
}
void sort::bubbleSort(int array[], int length)
{
//Bubble sort function
int i,j;
for(i = 0; i < 10; i++)
{
for(j = 0; j < i; j++)
{
if(array[i] > array[j])
{
int temp = array[i]; //swap
array[i] = array[j];
array[j] = temp;
}
}
}
}
/*void sort::merge(int* input, int p, int r) //the merge algorithm of the merge sort
{
int mid = (p + r) / 2;
int i1 = 0;
int i2 = p;
int i3 = mid + 1;
// Temp array
int x = r -p + 1;
int *temp;
temp = new int [x];
// Merge in sorted form the 2 arrays
while ( i2 <= mid && i3 <= r )
if ( input[i2] < input[i3] )
temp[i1++] = input[i2++];
else
temp[i1++] = input[i3++];
// Merge the remaining elements in left array
while ( i2 <= mid )
temp[i1++] = input[i2++];
// Merge the remaining elements in right array
while ( i3 <= r )
temp[i1++] = input[i3++];
// Move from temp array to master array
for ( int i = p; i <= r; i++ )
input[i] = temp[i-p];
}
void sort::merge_sort(int *input, int p, int r) //the merge sort algorithm
{
if ( p < r ) //When p and r are equal the recursion stops and the arrays are then passed to the merge function.
{
int mid = (p + r) / 2;
merge_sort(input, p, mid); //recursively calling the sort function in order to break the arrays down as far as possible
merge_sort(input, mid + 1, r);//recursively calling the sort function in order to break the arrays down as far as possible
merge(input, p, r); //merge function realigns the smaller arrays into bigger arrays until they are all one array again
}
}*/
void sort::shellSort(int array[], int length) //Shell sort algorithm
{
int gap, i, j, temp;
for( gap = length / 2; gap > 0; gap /= 2) //gap is the number of variables to skip when doing the comparisons
{
for( i = gap; i < length; i++) //This for loop sets the variable to use as the gap for the comparisons
{
for (j = i - gap; j >= 0 && array[j] > array[j + gap]; j -= gap)
{
temp = array[j]; //the array variables are swapped
array[j] = array[j + gap];
array[j + gap] = temp;
}
}
}
}
And my driver file:
#include "sort.h"
#include <iostream>
using namespace std;
int main()
{
int bubbleArray1[25]; //these are the arrays to be sorted. three for each sort. each has a length of 25, 10000, or 100000.
int bubbleArray2[10000];
int bubbleArray3[100000];
int mergeArray1[25];
int mergeArray2[10000];
int mergeArray3[100000];
int shellArray1[25];
int shellArray2[10000];
int shellArray3[100000];
sort Sorts;
Sorts.random1(bubbleArray1);
Sorts.random1(mergeArray1);
Sorts.random1(shellArray1);
Sorts.random2(bubbleArray2);
Sorts.random2(mergeArray2);
Sorts.random2(shellArray2);
Sorts.random3(bubbleArray3);
Sorts.random3(mergeArray3);
Sorts.random3(shellArray3);
cout << "BubbleSort1 is now being sorted.\n";
Sorts.bubbleSort(bubbleArray1, 25);
cout << "BubbleSort2 is now being sorted.\n";
Sorts.bubbleSort(bubbleArray2, 10000);
cout << "BubbleSort3 is now being sorted.\n";
Sorts.bubbleSort(bubbleArray3, 100000);
cout << "End bubble sorts.\n";
/*cout << "MergeSort1 is now being sorted.\n";
Sorts.merge_sort(mergeArray1, 0, 25);
cout << "MergeSort2 is now being sorted.\n";
Sorts.merge_sort(mergeArray2, 0, 10000);
cout << "MergeSort3 is now being sorted.\n";
Sorts.merge_sort(mergeArray3, 0, 100000);
cout << "End merge sorts.\n";*/
cout << "ShellSort1 is now being sorted.\n";
Sorts.shellSort(shellArray1, 25);
cout << "ShellSort1 is now being sorted.\n";
Sorts.shellSort(shellArray2, 10000);
cout << "ShellSort1 is now being sorted.\n";
Sorts.shellSort(shellArray3, 100000);
cout << "End shell sorts.\n";
cout << "Array\tElements\n";
cout << "BubbleSort1\t";
for(int i = 0; i < 25; i++)
{
cout << bubbleArray1[i] << " ";
}
cout << "\nMergeArray1\t";
for(int i = 0; i < 25; i++)
{
cout << mergeArray1[i] << " ";
}
cout << "\nShellArray1\t";
for(int i = 0; i < 25; i++)
{
cout << shellArray1[i] << " ";
}
return 0;
}
I know it's a lot of code. And there are probably many ways I could make the code better.
I would just like to know what's causing the error up above since I can't find it using my compiler.
You are allocating too much memory on the stack. Variables with 'automatic' storage class go on the stack. Allocate heap instead.
So, instead of:
int shellArray3[100000];
Do:
int* shellArray3 = new int[100000];
Or better yet, use std::vector.
If you don't want to use heap memory, you could also use the static storage class for something like this. To do that:
static int shellArray3[100000];
That will allocate one instance of the variable for the whole program rather than allocating a copy for each function entry on the stack.