Code Exiting on above 500,000 number of input - c++

I was performing sorting algorithm to calculate their runtime to execute, in which I was giving millions of number of input to sort, but my code is exiting on above 500,000 input and not showing any output. Is there anyway I can solve it.
int size;
cout<<"Enter size of the array: "<<endl;
cin>>size;
int a[size];
for(int i=0;i<size;i++)
{
a[i]=rand()%size;
}
int temp = 0;
double cl=clock();
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (a[j] < a[i])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
double final=clock()-cl;
cout<<final/(double)CLOCKS_PER_SEC;
}

You code crashes on 500'000 input because of stack overflow, you're allocating array on stack of too big size:
int a[size];
Stack size is usually few megabytes at most.
Also it is probably an extensions not of all compilers to have dynamically allocated array on stack, usually size should be a compile time constant.
To overcome stack crash either you have to use std::vector which can provide any size as big as there is free memory, for that do:
std::vector<int> a(size);
(also #include <vector>). Or you may use dynamically allocated array through new operator:
int * a = new int[size];
For this case don't forget to do delete[] a; at the end of program (see docs here).
Don't forget that input 500'000 takes very much of time using your bubble sort. For example 10 times less, 50'000, takes around 10 seconds on my machine.
Full working code using std::vector plus code formatting:
Try it online!
#include <iostream>
#include <vector>
using namespace std;
int main() {
int size;
cout << "Enter size of the array: " << endl;
cin >> size;
std::vector<int> a(size);
for (int i = 0; i < size; i++) {
a[i] = rand() % size;
}
int temp = 0;
double cl = clock();
for (int i = 0; i < size; i++) {
for (int j = i + 1; j < size; j++) {
if (a[j] < a[i]) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
double final = clock() - cl;
cout << final / (double)CLOCKS_PER_SEC;
}

Related

Finding max value in a array

I'm doing a program that finds the max value in a array. I done it but I found a strange bug.
#include<iostream>
using namespace std;
int main() {
int n; //input number of elements in
cin >> n;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i]; //input array's elements
} int max_value = arr[0];
for (int i = 1; i <= n; i++) {
if (arr[i] > max_value) {
max_value = arr[i];
}
} cout << max_value;
return 0;
}
When I put 5 as first line for the number of elements and 2, 7, 6, 8, 9 as the elements of the array. It returns 16 instead of 9. Please help
In Arrays the first index starts with 0 and ends in n - 1 assuming the array is of length n
so when looping from i = 1 to i <= n. n is now larger than n - 1.
the solution would be to start from 0 and end at i < n hence:
#include<iostream>
using namespace std;
int main() {
int n; //input number of elements in
cin >> n;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i]; //input array's elements
} int max_value = arr[0];
for (int i = 0; i < n; i++) {
if (arr[i] > max_value) {
max_value = arr[i];
}
}
cout << max_value;
return 0;
}
you could also use the std::max function like so:
for(int i = 0; i < n; i ++) {
max_value = max(max_value, arr[i]);
}
The other posts already pointed out problem in your code.
You should be aware of that int arr[n]; is not permitted in standard C++.
[GCC and CLANG compiler support it in C++ as an extension]
An alternative is to allocate memory dynamically:
int *arr = new int[n];
and to find maximum value you can use std::max_element:
int max_value = *(std::max_element(arr, arr + n));
Instead of dynamic array, its better to use vector STL (make yourself familiar with Containers Library). You can do:
std::vector <int> arr;
for (int i = 0; i < n; i++) {
int input;
std::cin >> input;
arr.push_back(input);
}
int max_value = *std::max_element(arr.begin(), arr.end());
std::cout << "Max element is :" << max_value << std::endl;
in your second for do this
for (int i = 1; i < n; i++) {
if (arr[i] > max_value) {
max_value = arr[i];
}
delete '=' from i <= n because i is index which start from 0
and instead of this
int arr[n];
do this
int *arr = new int[n];

access violation in pointer allocation

I want to put random data into arr (pointer allocation). How can I put data into that dynamic allocation?
typedef unique_ptr<unique_ptr<int[]>[]> uniquePtr;
uniquePtr arr = make_unique<unique_ptr<int[]>[]>(size);
srand(time(NULL));
cout << "size: " << endl;
cin >> size;
int max = size * size;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
arr[i][j] = rand() % max; //error!
}
}
Type of arr[i][j] is int.
When I tried this code,
arr[i][j] = new int(rand() % max);
but, the error is
arr[i][j] is int type and new int(~) is int* type
I want to put random int data into arr allocation.
The problem is you did not dynamically allocate the second dimension.
#include <iostream>
#include <memory>
using namespace std;
int main() {
int size = 5;
typedef unique_ptr<unique_ptr<int[]>[]> uniquePtr;
uniquePtr arr = make_unique<unique_ptr<int[]>[]>(size);
srand(time(NULL));
cout << "size: " << endl;
cin >> size;
int max = size * size;
for (int i = 0; i < size; i++) {
// Dynamically allocate the row
arr[i] = make_unique<int[]>(size);
for (int j = 0; j < size; j++) {
arr[i][j] = rand() % max;
}
}
return 0;
}
I put this online here: https://ideone.com/llAvTD

Passing 2D array to a function without using vectors [duplicate]

This question already has answers here:
Passing a 2D array to a C++ function
(17 answers)
Closed 1 year ago.
I am writing a program to print the sum of the elements of a user entered square matrix in the form of a 2D array without using vector. However I am getting 2 errors:
Error 1: error:array has incomplete element type 'int []'.
Error 2:
error: expected expression cout<<sumarr(arr[][]
This is my program:
int sumarr(int arr[][]) // ERROR 1
{
// finging no. pf rows(or coloums) of the square matrix
int n = sizeof(arr) / (2 * sizeof(int));
int sum = 0;
for (int i = 0; i < n; i++) // calculating sum of elements
{
for (int j = 0; j < n; j++)
{
sum += arr[i][j];
}
}
}
int main()
{
int n; // No. of rows(or coloumns) of the square matrix
cin >> n;
int arr[n][n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++) // inputting array elements
{
cin >> arr[i][j];
}
}
cout << sumarr(arr[][]); // ERROR 2
return 0;
}
Can someone suggest why I am getting these errors and how to resolve them?
In the function parameter (Error 1) you'll need to specify at least the last dimension of the array:
int sumarr(int arr[][SIZE]){ /*...*/}
In the call to the function you need to use the array name only, no dereferencing necessary (Error 2):
cout << sumarr(arr);
The problem then becomes the fact that Variable Length Arrays are not allowed in C++, so you probably should rethink the possibility of using vectors for this task.
Another thing worth mentioning is that sizeof(arr) inside the function will not render you the size of the array but the size of the pointer, which is what arr becomes when passed as an argument.
Alternatively you can manually allocate memory for the array, it could look more or less like this:
Live sample
#include <iostream>
#include <cassert>
// since sizeof arr can't work you should pass the size as argument
int sumarr(int **arr, int n)
{
assert(n > 0 && n < 1000); // confirm that n is valid, > 0 and a suitable upper limit
int sum = 0;
for (int i = 0; i < n; i++) //calculating sum of elements
{
for (int j = 0; j < n; j++)
{
// input and sum in the same loop will save you a O(N^2) operation
std::cin >> arr[i][j];
sum += arr[i][j];
}
}
return sum;
}
int main()
{
int n; //No. of rows(or columns) of the square matrix
std::cin >> n;
// memory allocation for 2D array
int **arr = new int *[n];
for (int i = 0; i < n; i++)
{
arr[i] = new int[n];
}
//end
int sum = sumarr(arr, n); // passing array and size
std::cout << "Sum: " << sum;
// freeing memory after use
for (int i = 0; i < n; i++)
{
delete [] arr[i];
}
delete [] arr;
//end
}

C++ why is there a segmentation fault in my pointer selection sort?

Below is my c++ code. I am trying to implement a selection sort using pointers (start and end). The code compiles, but I am getting a segmentation fault before it will sort the random generated list (currently only prints the random numbers).
Any help as to why this is and how to fix it would be greatly appreciated.
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
using namespace std;
void selectionSort(int *start, int *stop) {
for (int i = *start; i < *stop - 1; ++i) {
int min = i;
for (int j = i + 1; j < *stop; ++j) {
if ((&start[0])[j] < (&start[0])[min])
min = j;
}
swap((&start[0])[i], (&start[0])[min]);
}
}
int main()
{
int size = 10;
int* data = new int[size];
for (int i = 0; i < size; ++i)
{
data[i] = rand() % size;
}
for (int k = 0; k < size; k++)
{
cout << data[k] << " ";
}
cout << endl;
selectionSort(data, data+size);
for (int j = 0; j < size; j++)
{
cout << data[j+1] << " ";
}
return 0;
}
The general logic in your function is in the right direction. However, you seem to be confused between values of the elements of the array and the indexing used to access the elements of the array.
The line
for (int i = *start; i < *stop - 1; ++i)
shows the first signs of the confusion.
You are initializing i with the value of the first element of the array and incrementing the value in the subsequent iterations of the loop. That is not correct. Incrementing the value of the first element of the array does not make logical sense.
*stop causes undefined behavior since stop points to a place one past the last valid element.
You need to use int* i, int* j, and int* min to properly sort the elements. That also means updating almost the entire function accordingly. Here's an updated function that works for me.
void selectionSort(int *start, int *stop) {
for (int* i = start; i < (stop - 1); ++i) {
int* min = i;
for (int* j = i + 1; j < stop; ++j) {
if (*j < *min)
{
min = j;
}
}
swap(*i, *min);
}
}
Also, the following lines in main are not correct. You end up accessing the array using an out of bounds index.
for (int j = 0; j < size; j++)
{
cout << data[j+1] << " ";
}
Replace them by
for (int k = 0; k < size; k++)
{
cout << data[k] << " ";
}

Resizing dynamic array in c++

I have some code that is producing unexpected results. Here is the code:
#include <iostream>
using namespace std;
int **nums;
int size;
void A(int** arr)
{
int **resize;
resize = new int*[size*2];
for(int i = 0; i < size; i++)
resize[i] = new int(*arr[i]);
cout << endl;
arr = resize;
size *= 2;
delete[] resize;
}
int main()
{
size = 10;
nums = new int*[size];
for(int i = 0; i < size; i++)
nums[i] = new int(i);
for(int i = 0; i < size; i++)
cout << *nums[i] << endl;
A(nums);
cout << endl;
for(int i = (size / 2); i < size; i++)
nums[i] = new int(i);
for(int i = 0; i < size; i++)
cout << *nums[i] << endl;
}
The function A(int** arr) works fine as far as I can tell and actually resizes the array. However, in the last for loop in main(), when the array is printing, the first two elements of the array are not 0 and 1 like it is supposed to be. Here is the result I am getting:
0
1
2
3
4
5
6
7
8
9
16331248
16331712
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Those first two ints after the space are different each time the program is executed. After some debugging I found out that the first two elements print correctly until the iterator i=13 in the second to last for loop in main(). Then the first two elements in the array take on some large numbers. I am not sure why this is happening and I have been working on this for a couple of hours now :( Any help is appreciated.
A() is not modifying nums to point at the new array. Even if it were, it is deleting the new array, so nums would end up pointing at invalid memory. You need to declare the arr parameter as a reference, and delete the old array instead of the new array:
void A(int** &arr)
{
int **resize;
resize = new int*[size*2];
for(int i = 0; i < size; i++)
resize[i] = new int(*arr[i]);
cout << endl;
delete[] arr;
arr = resize;
size *= 2;
}
For what you are attempting, I think you have too much indirection. Try removing a level:
#include <iostream>
using namespace std;
int *nums;
int size;
void A(int* &arr)
{
int *resize;
resize = new int[size*2];
for(int i = 0; i < size; i++)
resize[i] = arr[i];
cout << endl;
delete[] arr;
arr = resize;
size *= 2;
}
int main()
{
size = 10;
nums = new int[size];
for(int i = 0; i < size; i++)
nums[i] = i;
for(int i = 0; i < size; i++)
cout << nums[i] << endl;
A(nums);
cout << endl;
for(int i = (size / 2); i < size; i++)
nums[i] = i;
for(int i = 0; i < size; i++)
cout << nums[i] << endl;
delete[] nums;
}
Since you are using C++, you should be using a std::vector instead of a raw array, then you can eliminate A() altogether:
#include <iostream>
#include <vector>
using namespace std;
vector<int> nums;
int main()
{
nums.resize(10);
for(int i = 0; i < nums.size(); i++)
nums[i] = i;
for(int i = 0; i < nums.size(); i++)
cout << nums[i] << endl;
nums.resize(nums.size()*2);
cout << endl << endl;
for(int i = (nums.size() / 2); i < nums.size(); i++)
nums[i] = i;
for(int i = 0; i < nums.size(); i++)
cout << nums[i] << endl;
}
First of all, your function, A, does not resize anything. It prints a newline character to standard output, it multiplies the global size variable by 2, and then it leaks some memory. That's it.
Now, because it multiplies size by 2 (going from 10, to 20), you run into a problem, here:
for(int i = (size / 2); i < size; i++)
nums[i] = new int(i);
Here, you are trying to access elements 10 through 19 of the array which nums points to. But the array which nums points to only has 10 elements (numbered 0 through 9), so your code has undefined behavior.