passing modified array values back to main function in C++ - c++

Write a reverse function that takes an integer array and its length as arguments. Your
function should reverse the contents of the array, leaving the reversed values in the original
array, and return nothing.
#include<iostream>
using namespace std;
void printArray(int a[], const int n)
{
for(int i=0;i<n;i++)
{
cout<<a[i];
i!=n-1 ? cout<<", " : cout<<"";
}
}
void reverse(int a[], const int n)
{
int reverse[n];
for(int i=0;i<n;i++)
{
reverse[n-1-i]=a[i];
}
a = reverse;
}
int main()
{
int *a,n;
cin>>n;
a = new int[n];
for(int i=0;i<n;i++)
a[i]=0;
a[0]=1;
reverse(a,n);
printArray(a,n);
delete [] a;
a = NULL;
return 0;
}
After calling reverse function the array from main is not modifying, please advice! :(

You can't assign one array to another. Instead copy from reverse to back into a:
std::copy(reverse, reverse + n, a);
Or possibly
memcpy(a, reverse, n * sizeof(int));

You are not copying the data from reverse back to a - you are instead pointing it (a) to a memory location that will no longer exist (be valid) after your function returns. You need to copy the values from reverse back to a. And I would recommend not using the same name for a function and a variable.
Try
void reverse(int a[], const int n)
{
int reverse[n];
for(int i=0;i<n;i++)
{
reverse[n-1-i]=a[i];
}
for(int i=0;i<n;i++)
{
a[i]=reverse[i];
}
}
As was pointed out in comments, the above shows one way of getting the reversed data into array a. It is not the only way - memcpy is considered a more efficient function to use. Even more efficient would be to do in place reversal - this would require a loop of just n/2 iterations while the above loops for 2n and is thus about 4x less efficient.
I recommend that you study all the answers provided - they highlight different aspects of memory handling, code efficiency etc.; something to learn from all of them.

Pointers! They're really useful.
void reverse (int *a, const size_t n)
{
int *b = a + n - 1;
while (b > a)
{
const int swap_value = *a;
*a = *b;
*b = swap_value;
++a;
--b;
}
}

Aha, you know you should pass int a[], a pointer to a, to reverse(), but you still encounter the same problem. You can't modify the pointer stored in a, unless you pass &a to reverse().

Related

C++ malloc(): corrupted top size on loop

I'm trying to create a function printarr that prints a dynamically sized array. However, whenever I try to run the code I get the error above. I tried copying code I found online as well, but get the same error, so I'm wondering if there's something wrong with my installation, or another part of the code is somehow affecting it. The entire thing seems super simple, which makes me even more stumped. Here's the code:
#include <iostream>
using namespace std;
//Generates an array with k inversions of size n
int* generate_k_inversion(int k, int n){
int *arr=new int(n);
//Check if number of inversions is possible
if(k>(n*(n-1)/2)){
cout<<"Impossible number of inversions!";
throw(-1);
}
//Loop to generate points
for(int i=0;i < n;i++){
arr[i]=i;
}
//Loop to invert
return arr;
}
//Copies dynamic arrays of size n
int* copy(int* arr1,int n){
int* arr2=new int(n);
for(int i=0;i<n;i++){
arr2[i]=arr1[i];
}
return(arr2);
}
//Generates output of best and worst cases of bubble and insertion sort in integers of size n
void test1(int n){
//generate best case
int *arrb1=generate_k_inversion(0,n);
int *arrb2=copy(arrb2,n);
delete [] arrb1;
delete [] arrb2;
//generate worst case
int *arrw1=generate_k_inversion((n*(n-1)/2),n);
int *arrw2=copy(arrw2,n);
delete [] arrw1;
delete [] arrw2;
}
//Prints a dynamic array arr of size n
void printarr(int* arr, int n)
{
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
}
//Just initialize both tests
int main(){
int size=10;
int* arr1=generate_k_inversion(0,size);
printarr(arr1,size);
delete [] arr1;
}
Thanks for the help
The line
int *arr=new int(n);
will allocate memory for a single int and initialize that int to n.
Therefore, the loop
for(int i=0;i < n;i++){
arr[i]=i;
}
will access arr out of bounds, causing undefined behavior.
What you probably want is to write
int *arr=new int[n];
instead, which will allocate memory for n values of type int.

Suffix Array sort function

Here I am trying to use inbuilt sort function. 's' is the array which stores the index. I am trying to sort this array according to suffix strings. If I am using qsort() function it works fine. But as soon as sort() used it sorts simply s array, doesn't recognize sort according to the suffixes in str. Please suggest me suitable changes for sort function. qsort() function is denoted in comment.
here is my code
string str;
int s[50005];
long long l;
//for qsort()
int cmp(const void *a,const void *b)
{
return (strcmp((str+ *((int*)a)),(str+ *((int*)b))));
}
//for sort() this does not works fine
int cmp1(int a,int b)
{
return (strcmp((str.c_str()+ a),(str.c_str()+ b)));
}
code for suffix array
void suffix_array(int n)
{
int i;
//initially 's' is initialized with all index
for(i=0;i<n;i++)
s[i]=i;
// qsort(s,n,sizeof(int),cmp); this works fine
sort(s,s+n,cmp1);
}
main function
int main()
{
int n,c;
scanf("%d",&n);
while(n--) {
cin>>str;
//scanf("%s",str);
l = str.length();
suffix_array(l);
for(int i=0;i<l;i++)
cout<<s[i]<<" ";
}
return 0;
}

bad_alloc exception while implementing the merge sort for larger arrays

I'm implementing the merge sort algorithm using C++. An exception(bad_alloc) is raised, while sorting larger arrays. Since i'm new to C++ i have no idea about how to get rid of this error. The answer i'm willing is not handling the exception, but the reason.
Here's my main method where i initially calls merge_sort function.
int *arr;
int main(){
int limits[2]={10,10000000}; //numbers of elements that should be in an array at each iteration
for(int l=0;l<sizeof(limits)/sizeof(*limits);l++){
cout<<"\n"<<endl;
arr=new int[limits[l]];
for(int cnt=0;cnt<limits[l];cnt++){ //creating the random array using random numbers
int temp=rand()%2147483647;
arr[cnt]=temp;
}
clock_t t;
t=clock();
cout<<"\nNumber of elements : "<<limits[l]<<endl;
merge_sort(0,limits[l]-1); //calling the merge sort function
cout<<endl;
t=clock()-t;
cout<<"The time taken : "<<t<<endl;
delete[] arr;
}
cin.get();
return 0;
}
Up to 1000000 elements this works fine. I'm having the trouble when sorting the array of size 10000000.
Here's the full code for test purposes.
#include<iostream>
#include<string.h>
#include<limits>
#include<time.h>
#include<stdlib.h>
using namespace std;
void merge_sort(int i,int j);
void merge(int i,int temp,int j);
int *arr;
//main method
int main(){
int limits[2]={10,10000000}; //numbers of elements that should be in an array at each iteration
for(int l=0;l<sizeof(limits)/sizeof(*limits);l++){
cout<<"\n"<<endl;
arr=new int[limits[l]];
for(int cnt=0;cnt<limits[l];cnt++){ //creating the random array using random numbers
int temp=rand()%2147483647;
arr[cnt]=temp;
}
clock_t t;
t=clock();
cout<<"\nNumber of elements : "<<limits[l]<<endl;
merge_sort(0,limits[l]-1); //calling the merge sort function
t=clock()-t;
cout<<"The time taken : "<<t<<endl;
delete[] arr;
}
cin.get();
return 0;
}
//method implementing the merge sort algorithm
void merge_sort(int i,int j){
if(i<j){
int temp=(i+j)/2;
merge_sort(i,temp);
merge_sort(temp+1,j);
merge(i,temp,j);
}
return;
}
//method implementing the merge algorithm
void merge(int i,int temp,int j){
int n1=temp-i+2; //calculating the sub array lengthes
int n2=j-temp+1;
int *L=NULL;
int *R=NULL;
L=new int[n1]; //dynamically initializing the sub left and right hand side arrays
R=new int[n2];
for(int x=0;x<n1-1;x++){
L[x]=arr[i+x];
}
for(int y=0;y<n2-1;y++){
R[y]=arr[temp+y+1];
}
L[n1-1]=numeric_limits<int>::max(); //adding the largest possible integer to the end of each array
R[n2-1]=numeric_limits<int>::max();
int a=0;
int b=0;
for(int k=i;k<=j;k++){ //merging the two sub arrays
if(L[b]>R[a] ){
arr[k]=R[a];
a++;
}
else{
arr[k]=L[b];
b++;
}
}
}
It's better if someone can give me the reason behind this rather than a fix. Thanks!
Your merge function has a memory leak, and a very big one:
L = new int[n1];
R = new int[n2];
The memory is never deallocated. If you're coming from a language such as Java or C#, you see that C++ works differently. There is no automatic garbage collection, and using new[] in C++ requires you use delete[] at some point, else you get a memory leak.
But a better solution would be to replace those lines with this:
#include <vector>
//...
// Remove the int *L and int *R declarations.
//
std::vector<int> L(n1);
std::vector<int> R(n2);
You should always think vector first over using new[]/delete[] to avoid these types of memory errors.
Once you make those changes, the program will complete, but takes a while (at least it did with Visual Studio 2013 in debug mode).
In release mode, the time took for 10000000 was 3,300 ms.
Edit: For an experiment, I used the following code to see what would happen if the vector was moved out of the function, and just reused:
std::vector<int> L;
std::vector<int> R;
void merge(int i, int temp, int j){
int n1 = temp - i + 2;
int n2 = j - temp + 1;
L.resize(n1);
R.resize(n2);
//...
}
So I made the vectors global. The amount of time it took was closer to 2,000 ms, so approximately 1,000 ms faster. The advantage is the usage of resize to resize the vectors as opposed to redeclaring them, or using new[]/delete[] multiple times.

Inputing the Size of a 2-dimentional Array

In my code I input the sizes of both dimensions and then declare a two-dimensional array. My question is, how do I use that array as a function parameter? I know that I need to write the number of columns in the function specification but how do I pass the number of columns?
void gameDisplay(gameCell p[][int &col],int a,int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i][j].getStat()==closed)cout<<"C ";
if(p[i][j].getStat()==secure)cout<<"S ";
if(p[i][j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i][j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i][j].getNum()==0)cout<<"0 ";
else cout<<p[i][j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[][col],row,col);
}
I tried this way but it doesn't work.
Thank you.
In C++, you cannot have variable length arrays. That is, you can't take an input integer and use it as the size of an array, like so:
std::cin >> x;
int array[x];
(This will work in gcc but it is a non-portable extension)
But of course, it is possible to do something similar. The language feature that allows you to have dynamically sized arrays is dynamic allocation with new[]. You can do this:
std::cin >> x;
int* array = new int[x];
But note, array here is not an array type. It is a pointer type. If you want to dynamically allocate a two dimensional array, you have to do something like so:
std::cin >> x >> y;
int** array = new int*[x]; // First allocate an array of pointers
for (int i = 0; i < x; i++) {
array[i] = new int[y]; // Allocate each row of the 2D array
}
But again, this is still not an array type. It is now an int**, or a "pointer to pointer to int". If you want to pass this to a function, you will need the argument of the function to be int**. For example:
void func(int**);
func(array);
That will be fine. However, you almost always need to know the dimensions of the array inside the function. How can you do that? Just pass them as extra arguments!
void func(int**, int, int);
func(array, x, y);
This is of course one way to do it, but it's certainly not the idiomatic C++ way to do it. It has problems with safety, because its very easy to forget to delete everything. You have to manually manage the memory allocation. You will have to do this to avoid a memory leak:
for (int i = 0; i < x; i++) {
delete[] array[i];
}
delete[] array;
So forget everything I just told you. Make use of the standard library containers. You can easily use std::vector and have no concern for passing the dimensions:
void func(std::vector<std::vector<int>>);
std::cin >> x >> y;
std::vector<std::vector<int>> vec(x, std::vector<int>(y));
func(vec);
If you do end up dealing with array types instead of dynamically allocating your arrays, then you can get the dimensions of your array by defining a template function that takes a reference to an array:
template <int N, int M>
void func(int (&array)[N][M]);
The function will be instantiated for all different sizes of array that are passed to it. The template parameters (dimensions of the array) must be known at compile time.
I made a little program:
#include <iostream>
using namespace std;
void fun(int tab[][6], int first)
{}
int main(int argc, char *argv[])
{
int tab[5][6];
fun(tab, 5);
return 0;
}
In function definition you must put size of second index. Number of column is passed as argument.
I'm guessing from Problems with 'int' that you have followed the advices of the validated question and that you are using std::vector
Here is a function that returns the number of columns of an "array" (and 0 if there is a problem).
int num_column(const std::vector<std::vector<int> > & data){
if(data.size() == 0){
std::cout << "There is no row" << std::endl;
return 0;
}
int first_col_size = data[0].size();
for(auto row : data) {
if(row.size() != first_col_size){
std::cout << "All the columns don't have the same size" << std::endl;
return 0;
}
}
return first_col_size;
}
If you're using C-style arrays, you might want to make a reference in the parameter:
int (&array)[2][2]; // reference to 2-dimensional array
is this what you're looking for?
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
example . . .
#include <iostream>
#include <stdio.h>
int* generate2DArray(int rowSize, int colSize);
int random(int min, int max);
int main()
{
using namespace std;
int row, col;
cout << "Enter row, then colums:";
cin >> row >> col;
//fill array and display
int *ptr = generate2DArray(row, col);
for(int i=0; i<row; ++i)
for(int j=0; j<col; ++j)
{
ptr[i,j] = random(-50,50);
printf("[%i][%i]: %i\n", i, j, ptr[i,j]);
}
return 0;
}
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
int random(int min, int max)
{
return (rand() % (max+1)) + min;
}
instead of accessing p[i][j] you should access p[i*b + j] - this is actually what the compiler do for you since int[a][b] is flattened in the memory to an array in size of a*b
Also, you can change the prototype of the function to "void gameDisplay(gameCell p[],int a,int b)"
The fixed code:
void gameDisplay(gameCell p[],int a, int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i*a +j].getStat()==closed)cout<<"C ";
if(p[i*a +j].getStat()==secure)cout<<"S ";
if(p[i*a +j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i*a +j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i*a +j].getNum()==0)cout<<"0 ";
else cout<<p[i*a +j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[],row,col);
}

implementation counting sort

here is code for counting sorting
#include <iostream>
using namespace std;
int main(){
int a[]={2,3,1,2,3};
int n=sizeof(int)/sizeof(int);
int max=a[0];
for (int i=1;i<n;i++) {
if (a[i]>max) {
max=a[i];
}
}
int *output=new int[n];
for (int i=0;i<n;i++) {
output[i]=0;
}
int *temp=new int[max+1];
for (int i=0;i<max+1;i++) {
temp[i]=0;
}
for (int i=0;i<n;i++){
temp[a[i]]=temp[a[i]]+1;
}
for (int i=1;i<max+1;i++) {
temp[i]=temp[i]+temp[i-1];
}
for (int i=n-1;i>=0;i--) {
output[temp[a[i]]-1]=a[i];
temp[a[i]]=temp[a[i]]-1;
}
for (int i=0;i<n;i++) {
cout<<output[i]<<" ";
}
return 0;
}
but output is just 2,only one number. what is wrong i can't understand please guys help me
int n=sizeof(int)/sizeof(int);
is wrong. That just assigns 1 to n.
You mean
int n=sizeof(a)/sizeof(int);
I've not looked beyond this. No doubt there are more problems, but this is the most significant.
This is the kind of thing you can work out very easily with a debugger.
Look at this expression:
int n=sizeof(int)/sizeof(int);
What do you think the value of n is after this? (1)
Is that the appropriate value? (no, the value should be 5)
Does that explain the output you are seeing? (yes, that explains why only one number is shown)
My advice would be that if you're going to do this in C++, you actually try to use what's available in C++ to do it. I'd look up std::max_element to find the largest element in the input, and use an std::vector instead of messing with dynamic allocation directly.
When you want the number of elements in an array in C++, you might consider a function template something like this:
template <class T, size_t N>
size_t num_elements(T const (&x)[N]) {
return N;
}
Instead of dumping everything into main, I'd also write the counting sort as a separate function (or, better, a function template, but I'll leave that alone for now).
// warning: Untested code:
void counting_sort(int *input, size_t num_elements) {
size_t max = *std::max_element(input, input+num_elements);
// allocate space for the counts.
// automatically initializes contents to 0
std::vector<size_t> counts(max+1);
// do the counting sort itself.
for (int i=0; i<num_elements; i++)
++counts[input[i]];
// write out the result.
for (int i=0; i<counts.size(); i++)
// also consider `std::fill_n` here.
for (int j=0; j<counts[i]; j++)
std::cout << i << "\t";
}
int main() {
int a[]={2,3,1,2,3};
counting_sort(a, num_elements(a));
return 0;
}