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.
Related
What am I doing wrong ???
It is giving me an error of segmentation fault .
I don't know what memory i'm accessing ??
#include <iostream>
using namespace std;
int main() {
int t;
int n;
int arr[n];
cin>>t;
cin>>n;
// taking array elements from user
for(int i=0; i<n;i++)
{
cin>>arr[i];
}
// reverse of the array
for(int i=n-1; i>=0;i--)
{
cout<<arr[i];
}
//code
return 0;
}
int n;
You've default initialised this variable. Thus, the value is indeterminate.
int arr[n];
Here, you use that indeterminate value. Thus, the behaviour of the program is undefined.
There are "data flow" languages where using a variable will stop execution waiting for you to initialise it later and continue. C++ isn't such language. You must initialise everything before using the value.
Besides that, n isn't a compile time constant expression. Because the size of the array variable isn't compile time conastant, the progarm is ill-formed in C++.
If you want an array to have a dynamic size, you can use dynamic storage. Simplest way to create a dynamic array is to use std::vector.
For starters you are trying to declare a variable length array
int n;
int arr[n];
Variable length arrays is not a standard C++ feature. Moreover you are using an uninitialized variable n as the size of the array.
Either declare the array with an expected maximum size or use standard container std::vector<int>. At least you should write provided that the compiler supports variable length arrays
int t;
int n = 1;
cin>>t;
cin>>n;
if ( n < 1 ) n = 1;
int arr[n];
//...
Also you are not reversing an array. You are trying to output an array in the reverse order.
To reverse an array you could use standard algorithm std::reverse or you can write an appropriate loop yourself as for example
for ( int i = 0; i < n / 2; i++ )
{
// or use std::swap( arr[i], arr[n-i-1] );
int tmp = arr[i];
arr[i] = arr[n-i-1];
arr[n-i-1] = tmp;
}
and then you can output the reversed array.
You are not allowed to define array with Unknown size in C++ so int arr[n]; is Wrong! and if you have to use arrays and not know the size of it , you should use dynamic array with Pointers like this : int* a = new int[n] and also Deallocate Heap memory with Delete []array_name at end of your program and if it is possible for you not use arrays It's better for you use vectors because the size of it is dynamic.
look at this with vectors :
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//by : Salar Ashgi
int main()
{
int k;
cout<<"Enter number of elements ?\n";
cin>>k;
vector<int> v;
cout<<"--------------------\n";
int x;
for(int i=0;i<k;i++)
{
cout<<"Enter num "<<i+1<<" : ";
cin>>x;
v.push_back(x);
}
reverse(v.begin(),v.end());//algorithm.h
cout<<"Reverse : \n";
for(int i=0;i<k;i++)
{
cout<<v[i]<<" ";
}
}
My goal in this program is to take two user entered arrays of a given size and merge them into one.
I'm able to successfully enter both arrays' size and their elements, but it fails to output the merged array- giving me this error:
"Error in `./a.out': free(): invalid pointer: 0x0..."
I've tried to debug but to no avail, I can't seem to figure out if I have incorrect syntax or I'm making an incorrect call.
Any help appreciated
#include<iostream>
using namespace std;
int* mergeArrays(int[], int[], int, int);
int arr1[0], arr2[0];
int main()
{
int size1, size2, i;
cout<<"Enter the first array's size : ";
cin>>size1;
int *arr1 = new int[size1];
cout<<"Enter the first array's elements : ";
for(i=0; i<size1; i++)
{
cin>>arr1[i];
}
cout<<"Enter the second array's size : ";
cin>>size2;
cout<<"Enter the second array's elements : ";
for(i=0; i<size2; i++)
{
cin>>arr2[i];
}
delete[] arr1;
delete[] arr2;
cout << mergeArrays;
}
int* mergeArrays(int arr1[], int arr2[], int size1, int size2){
int i, k, size;
int size3 = size1 + size2;
int *mergeArr = new int[size3];
for(i=0; i<size1; i++)
{
mergeArr[i]=arr1[i];
}
size=size1+size2;
for(i=0, k=size1; k<size && i<size2; i++, k++)
{
mergeArr[i]=arr2[i];
}
cout<<"The merged array is: \n";
for(i=0; i<size3; i++)
{
cout<<mergeArr[i]<<" ";
}
return mergeArr;
}
Your program exhibits undefined behavior, by way of a buffer overrun. arr2 is an array of zero size, arr2[i] is accessing out of bounds for any value of i.
Also, you call delete[] arr2 but arr2 was not allocated with new
#include <stdio.h>
#include <iostream>
using namespace std;
int* arr_test(int);
int main()
{
int n;
cin>>n;
int *new_arr;
new_arr=arr_test(n);
for (int i=0;i<n;i++)
new_arr[i]++;
for(int i=0;i<n;i++)
cout<<"new array "<< new_arr[i]<<endl;
return 0;
}
int* arr_test(int n)
{
int arr[n];
for (int i=0;i<n;i++)
cin>>arr[i];
for(int i=0;i<n;i++)
cout<<"old array "<< arr[i]<<endl;
return arr;
}
output:
2
20
10
old array 20
old array 10
Segmentation fault
I know why i'm getting segmentation fault because i'm accessing the memory which is not there i mean the array which has scope only on arr_test function. But I want to get that array. I tried "static" but it's saying arr[n] is not constant. I can make it global but I size of 'n' must get from user. How can I access that array?. If you have another method to get it please post it but remember the constraint arr size must be user given and array must be in arr_test function. Thanks in advance:)
Within your function arr_test the local variable arr[n] is placed on the stack but used as the return value.
When the function returns, the stack is cleared.
If you want to use a local variable as a return value, you should make sure it's not cleared when the function returns.
This can be obtained by declaring the local variable as static int arr[n];.
You return an array int arr[n]; which is destroyed after leaving scope of the function.
Try to return array allocated in memory:
int* arr_test(int n)
{
int* arr = new int[n];
for (int i=0;i<n;i++)
cin>>arr[i];
for(int i=0;i<n;i++)
cout<<"old array "<< arr[i]<<endl;
return arr;
}
But after than you need to delete allocated memory by delete [] new_arr;
Also you can use array reference to use array from automatic memory:
void arr_test2(int arrByReference[], int n)
{
for (int i=0;i<n;i++)
cin>>arrByReference[i];
for(int i=0;i<n;i++)
cout<<"old array "<< arrByReference[i]<<endl;
}
//...
int array[n];
arr_test2(array,n);
In this case you don't need to delete memory. It will be deleted when array will leave scope
In idiomatic C++, a dynamic array of int is pronounced std::vector<int>, not int[]. using namespace std; introduces many names into global scope, and is a recipe for subtle bugs.
#include <iostream>
#include <vector>
std::vector<int> arr_test(int);
int main()
{
int n;
cin>>n;
auto new_arr = arr_test(n);
std::for_each(new_arr.begin(), new_arr.end(), [](int & val){ ++val; });
std::for_each(new_arr.begin(), new_arr.end(), [](int val){ std::cout << "New array" << val << std::endl; });
return 0;
}
std::vector<int> arr_test(int n)
{
std::vector<int> arr(n);
std::copy_n(std::istream_iterator<int>(std::cin), n, new_arr.begin());
std::for_each(new_arr.begin(), new_arr.end(), [](int val){ std::cout << "Old array" << val << std::endl; });
return arr;
}
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.
I am using Code:Block.
Compiled the following code(no errors) and while running got segmentation fault.
void print(int size, int **a)
{
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
cout<<a[i][j]<<" ";/**Segmentation fault here**/
}
cout<<endl;
}
}
int main()
{
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int size = sizeof(a)/sizeof(a[0]);
print(size,(int **)a);
return 0;
}
I tried using different methods of passing the array:
void print(int size, int a[][4])
{
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int size = sizeof(a)/sizeof(a[0]);
print(size,a);
return 0;
}
I got no error, code ran successfully.
For the first code instead of using a[i][j], I tried with *(*(a+i)+j), got segmentation fault.
Then I debugged the first code at the point of segmentation fault and absorbed the following:
> p a
$1 = (int **) 0x22fd30
> p *a
$2 = (int *) 0x200000001
> p **a
Cannot access memory at address 0x200000001
I believe that a hold the first address of the 2d array. but for p **a there is a different address shown in the error message.
Then I ran the first code in http://ideone.com/ and encountered run time error. Where am I making mistake? and why the debugger showing different address?.
In your first example
void print(int size, int **a)
expects second argument of type pointer to pointer to int. But here
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
print(size,(int **)a);
you pass a variable of type array of 4 arrays of 4 ints. When you pass an array to function, array decays to pointer to its first element. So actually function print gets argument of type int *[4] - pointer to array of 4 ints which is not what print expects. That's an error. You hide this error from compiler telling him that a has type int **. It doesn't. Hence the segmentation fault.
In your second example
void print(int size, int a[][4])
expects an argument of type array of arrays of 4 ints. It decays to int *[4] which is exactly the type of a when it decays while passed to print function. No error here.
If you index an int**, in your case a[0] for example, the resulting type is int*. If you index that again, as in a[0][0], it will interpret the first element (being the integer 1) (or first two elements on 64-bit) as a pointer to int (int*) and attempt to dereference it, which is obviously incorrect and will usually lead to a segmentation fault.
Your C-style cast (int**) is translated to a reinterpret_cast. Which is why I don't like C-style casts as it's not always obvious what they do.
In short: with your cast to (int**) you're telling the compiler that it's an array of pointers to int, which it isn't: it's an array of int[4]'s.
Edit: my comment about 64-bit only holds for platforms where sizeof(int) is always 4. I believe on linux sizeof(int) == sizeof(int*).
Replace cout<<a[i][j]<<" "; with cout<<a[i*size+j]<<" ";
Problem you are facing is because of Data type of both is different. int arr[][] is different from int ** arr. Lets see from 1-d array when you declare int arr[], arr it is same as int *arr. When you try to access it arr[i] internally what compiler does *(arr+i). But when you declare int arr[][size] data type of arr is int (*arr)[size] which is different from int **arr. That's why you get error. see this Link
The following works for me:
Allocation and assignment:
int** foo( int N, int M)
{
int** arr;
arr = (int **)malloc(sizeof(int *)*N);
for(int i=0; i < N; i++) {
arr[i] = (int *)malloc(sizeof(int)*M);
}
int x=0;
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
arr[i][j]=x;
x++;
}
}
return arr;
}
Now you can use it like this:
void print(int size, int a[][4])
{
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
int N=2;
int M=3;
int** foo = bar(N,M);
print(arr,N,M);
}