Vectors in C++ , bucket sort : Segmentation fault - c++

In my code, I am trying to implement bucket sort and in my implementation I have tried using vectors, but unfortunately I end up with errors with respect to vector functions.
Code :
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void bucket_sort(vector<float> & , int); //vector is passed by reference
int main(){
vector<float> array;
float element;
int count;
cout << "\nEnter the size of the vector : ";
cin >> count;
cout << "\nEnter the elements into the vector : ";
for(vector<float>::size_type i = 0 ; i < count ; i++){
cin >> element;
array[i].push_back(element);
}
bucket_sort(array , count);
}
void bucket_sort(vector<float> array, int count){
vector<float> bucket;
for(int i = 0 ; i < count ; i++){
int bucket_index = count * array[i];
bucket[bucket_index].push_back(array[i]);
}
for(int i = 0 ; i < count ; i++)
sort(bucket[i].begin() , bucket[i].end());
int index = 0;
for(int i = 0 ; i < count ; i++)
for(int j = 0 ; j < bucket[i].size() ; j++)
array[index++].push_back(bucket[i][j]);
}
Errors :
bucket_sort.cpp: In function ‘int main()’:
bucket_sort.cpp:24:12: error: request for member ‘push_back’ in ‘array.std::vector<_Tp, _Alloc>::operator[]<float, std::allocator<float> >(i)’, which is of non-class type ‘float’
array[i].push_back(element);
^
bucket_sort.cpp: In function ‘void bucket_sort(std::vector<float>, int)’:
bucket_sort.cpp:36:24: error: request for member ‘push_back’ in ‘bucket.std::vector<_Tp, _Alloc>::operator[]<float, std::allocator<float> >(((std::vector<float>::size_type)bucket_index))’, which is of non-class type ‘float’
bucket[bucket_index].push_back(array[i]);
^
bucket_sort.cpp:40:18: error: request for member ‘begin’ in ‘bucket.std::vector<_Tp, _Alloc>::operator[]<float, std::allocator<float> >(((std::vector<float>::size_type)i))’, which is of non-class type ‘float’
sort(bucket[i].begin() , bucket[i].end());
^
bucket_sort.cpp:40:38: error: request for member ‘end’ in ‘bucket.std::vector<_Tp, _Alloc>::operator[]<float, std::allocator<float> >(((std::vector<float>::size_type)i))’, which is of non-class type ‘float’
sort(bucket[i].begin() , bucket[i].end());
^
bucket_sort.cpp:45:33: error: request for member ‘size’ in ‘bucket.std::vector<_Tp, _Alloc>::operator[]<float, std::allocator<float> >(((std::vector<float>::size_type)i))’, which is of non-class type ‘float’
for(int j = 0 ; j < bucket[i].size() ; j++)
^
bucket_sort.cpp:46:19: error: request for member ‘push_back’ in ‘array.std::vector<_Tp, _Alloc>::operator[]<float, std::allocator<float> >(((std::vector<float>::size_type)(index ++)))’, which is of non-class type ‘float’
array[index++].push_back(bucket[i][j]);
^
bucket_sort.cpp:46:40: error: invalid types ‘float[int]’ for array subscript
array[index++].push_back(bucket[i][j]);
Edited code :
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void bucket_sort(vector<float> & , int); //vector is passed by reference
int main(){
vector<float> array;
float element;
int count;
cout << "\nEnter the size of the vector : ";
cin >> count;
cout << "\nEnter the elements into the vector : ";
for(int i = 0 ; i < count ; i++){
cin >> element;
array.push_back(element);
}
bucket_sort(array , count);
cout << "\nSorted vector : ";
for(int i = 0 ; i < count ; i++)
cout << array[i] << " ";
}
void bucket_sort(vector<float>& array, int count){
vector<float> bucket[count];
for(int i = 0 ; i < count ; i++){
int bucket_index = count * array[i];
bucket[bucket_index].push_back(array[i]);
}
for(int i = 0 ; i < count ; i++)
sort(bucket[i].begin() , bucket[i].end());
int index = 0;
for(int i = 0 ; i < count ; i++)
for(int j = 0 ; j < bucket[i].size() ; j++)
array.push_back(bucket[i][j]);
}
Edit :
I have introduced the correction with respect to the push_back() but now upon running my code I hit a segmentation fault. Any suggestions?

push_back is method of vector, not element. To append element (with increasing vector size by 1) use array.push_back(123). To assign something to element use array[i] = 123.
If you want to fill vector using assignment, you have to resize vector first: array.resize(count).
To sort, wirte sort(array.begin() , array.end()).
bucket[i][j] is totally incorrect: bucket is one dimensional vector. You probably want bucket to be vector<vector<float>>.
for(int i = 0 ; i < count ; i++){
int bucket_index = count * array[i];
bucket[bucket_index].push_back(array[i]);
}
You have only count elements in bucket array but ask for count * array[i] element.

Your code have many problems.
Main problem is following:
You can not do this:
array[i].push_back(element);
You must do this instead:
array.push_back(element);
Later you do the same:
bucket[bucket_index].push_back(array[i]);
But this time, probably you need just:
bucket[bucket_index] = array[i];
Or if you want just to obtain a copy from vector called "array", you can just do:
bucket = array;
If you post comment what bucket_sort should do, I can provide future explanations.
Finally, I also would suggest you to add:
using MyVector = vector<float>;
Will safe you lots of typing.
Also you might define the function to use the vector by reference, because else it is copied and you probably do not want this:
void bucket_sort(MyVector &array, int count);

Instead of array[i].push_back(element), use array.push_back(element). Element will go at the position automatically as a for loop index.
So, at the end of loop, array will have count number of elements as desired by you.
Use this logic everywhere in the code.

Related

C++ code don't have errors but not giving output [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I am writing code for selection sort in c++. It gives no error when i compile it with the command g++ main.cpp -o main in powershell but when i run the code with ./main, it don't show anything. I tried with hello world program and it worked. I don't know why the selection sort code not working.
Here Is the code of Selection sort
#include<iostream>
using namespace std;
int main()
{
int n, a[n];
cout << "Enter the size of the array = ";
cin >> n;
cout << "Enter the numbers :" << endl;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int i = 0; i < n-1; i++)
{
for (int j = i+1; j < n; j++)
{
if (a[i] > a[j])
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
for (int b=0; b<n; b++)
{
cout<<a[b];
}
return 0;
}
There are 2 problems in your program.
Mistake 1
In Standard C++ the size of an array must be a compile time constant. So take for example,
int n = 10;
int arr[n] ; //INCORRECT because n is not a constant expression
The correct way to write the above would be:
const int n = 10;
int arr[n]; //CORRECT
Mistake 2
You're using an uninitialized variable which leads to undefined behavior. In particular when you wrote:
int n, a[n]; //here variable n is uninitialized and holds **indeterminate value**.
In the above statement, you are creating an int named n but since you have not explicitly initialized it, it holds an indeterminate value.
Next, you're using that garbage value as the size of the array a. But note that using uninitialized variable results in undefined behavior.
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior.
This is why it is advised that
always initialize built in types in local/block scope.
Solution
A better way would be to use std::vector as shown below.
#include <iostream>
#include <vector>
int main()
{
int n = 0; //always initialize built in types in local/block scope
std::cout<<"Enter size: "<<std::endl;
std::cin >> n;
//create a vector of size n
std::vector<int> a(n);
//iterate and ask for input
for(int i = 0; i < a.size(); ++i)
{
std::cout<<"Enter element: "<<std::endl;
std::cin >> a[i];
}
for (int i = 0; i < a.size() - 1; ++i)
{
int index = i;
for (int j = i + 1; j < a.size(); j++) {
if (a[j] < a[index])
index = j;
}
int temp = a[index];
a[index] = a[i];
a[i] = temp;
}
std::cout<<"The elements of the vector are:"<<std::endl;
//print the element of the vector
for(const int& elem: a)
{
std::cout<<elem<<std::endl;
}
return 0;
}
The output of the program can be seen here.
1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.
Always initialize variables. A declaration without initialization is a code smell, eg this one:
int n;
The issue immediately follows, because
int n, a[n];
uses n uninitialized. Compilers do a pretty good job at warning about this: https://godbolt.org/z/ErPY3x936. Before you initialize n, it has an indeterminate value. Using its value leads to undefined behavior. Further, a[n] is a variable length array (unless n is a constant expression), which is not part of standard C++. When you need an array whose size is only known at runtime, you can use a std::vector:
int n = 0;
cout << "Enter the size of the array = ";
cin >> n;
std::vector<int> arr(n);
You are trying to use a variable length array
int n, a[n];
Variable length arrays is nit a standard C++ feature. So you should avoid to use them. Instead use the standard container std::vector<int>.
Moreover the variable n is not initialized. So the declaration of the variable length array invokes undefined behavior.
Within the for loops where you are sorting the array there are too many swaps of elements of the array.
The selection sort algorithm assumes that a selected element in an array is swapped at most one time.
And there is the standard function std::swap that can be used instead of manually swapping elements.
Your program can look the following way
#include <iostream>
#include <utility>
#include <vector>
int main()
{
size_t n = 0;
std::cout << "Enter the size of the array (0 - exit): ";
std::cin >> n;
if ( n )
{
std::vector<int> v( n );
std::cout << "Enter the numbers :" << std::endl;
for ( auto &item : v )
{
std::cin >> item;
}
for ( std::vector<int>::size_type i = 0; i < v.size(); i++ )
{
auto min = i;
for ( auto j = i + 1; j < v.size(); j++ )
{
if ( v[j] < v[min] ) min = j;
}
if ( min != i ) std::swap( v[min], v[i] );
}
for ( const auto &item : v )
{
std::cout << item << ' ';
}
std::cout << std::endl;
}
return 0;
}.

Unknown compiler error in cout<< theoreticlly it works

#include <iostream>
using namespace std;
void matrice(int n){
cout<<"Input the number of the elements "<<endl;
cin>>n;
int D[n][n];
cout<<"Input the elements :";
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>D[i][j];
}
}
int min;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if( min=0>D[i-1][j-1]){
D[i-1][j-1]=min;
}
}
}
cout<<" The smallest element is : "<< min<<"and it is the"<< i <<" element ." ;
}
int main(){
int i, min ,j,n;
int n1;
cout<<"Decide: "<<endl;
cout<<"Matrice[1]"<<"\t"<<"Vekcor[2]"<<endl;
cin>>n1;
if(n1==1){
matrice(n);
}
else if(n1==2){
}
}
The problem is at line 22 at the cout and it gives this message:
C:\Users\use\Documents\Dev C++\void_vektor.cpp|22|error: no match for 'operator<<' (operand types are 'std::basic_ostream' and '')|
min is only visible in for loop scope because you have declared it inside of loop.
declared it here:
int min=D[0][0];
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (min > D[i - 1][j - 1])
{
D[i - 1][j - 1] = min;
}
}
}
cout << " Elementi me i vogel eshte : " << min;
also note that you have used uninitialized n in main and even though you will take it as input in function sending an uninitialized variable to a function might be problematic.
and also move declaration of int D[n][n]; after taking n as input.
cout<<"Input the number of the elements "<<endl;
cin>>n;
int D[n][n];
instead of your loops I suggest this which is easier:
int min=D[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (min > D[i][j])
{
D[i][j] = min;
}
}
}
cout << " Elementi me i vogel eshte : " << min;
also note that if you initialize min=0 you can't find min in array in which all of elements>0. I suggest min=[0][0].
The main issue is that you declare min inside the for loop, it will go out of scope as the loop exits.
The bizarre error message is likely because of the std::min function. This is a good case study on why not to use using namespace std;.
At first glance there are other issues in your code:
i, min and jare unused in main().
n is used uninitialized, this is undefined behaviour, furthermore C++ forbids variable-size array. If you need a variable length array you can use something like std::vector.
if(min = 0 > D[i-1][j-1]) is very strange, is that really what you need?
In the future you should use compiler warnings.
There's a fundamental problem here: the call matrice(n) in main uses the uninitialized value of n, so if your compiler supports that int D[n][n] syntax you have no idea how large the array actually is. Formally, the behavior is undefined. Informally, there's a 50/50 chance that you'll get a negative number, which doesn't make sense as an array size.

error: invalid initialization of non-const reference of type ‘std::vector<int>&’ from an rvalue of type ‘std::vector<int>*’

I am new to STL in C++. I have this piece of code in which I am trying to input values in each vector of array of vectors v. When I pass this array of vectors and a number to a function happiness, it gives the following error:
error: invalid initialization of non-const reference of type ‘std::vector<int>&’ from an rvalue of type ‘std::vector<int>*’
int val = happiness(n,v);
The code is here:
int main(){
int n;
cin >> n;
vector<int> v[10000];
//vector<int> v(10000);
//int val;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int temp;
cin >> temp;
v[i].push_back(temp);
}
}
int val = happiness(n,v);
// return 0;
}
Please let me know how should I understand this error and rectify it.
Here is the happiness function defined:
int happiness(int &num, vector<int> &vecvec[]){
vector<int> pdp(10000,0);
int sum = 0;
int tempsum = -100;
int max_curr_ind = -1;
int i,j;
for(i = 0; i < num; i++){
for(j = 0; j < num; j++){
if(vecvec[i,j] >= tempsum && j != max_curr_ind){
tempsum = vecvec[i,j];
max_curr_ind = j;
}
}
sum = sum + tempsum;
pdp[i,max_curr_ind] = sum;
tempsum = -100;
}
cout << pdp[i,max_curr_ind] << endl;
return pdp[i,max_curr_ind];
}
You may definitely want to replace this:
vector<int> v[10000];
//vector<int> v(10000);
//int val;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int temp;
cin >> temp;
v[i].push_back(temp);
}
}
with this:
vector<vector<int> > v;
for( int i=0; i<n; i++) {
vector<int> temp;
for( int j=0; j<n; j++) {
int tmp;
cin >> tmp;
temp.push_back( tmp );
}
v.push_back( temp );
}
And then define:
int happiness(int &num, vector<vector<int> >& vecvec)
to be able to pass v just as-is.
Let's dissect the error message:
invalid initialization of non-const reference of type ‘std::vector<int>&’ ...
... int val = happiness(n,v);
This tells you that your function expects a std::vector<int>& in the function call int val = happiness(n,v).
from an rvalue of type ‘std::vector<int>*’
This tells you what you are actually providing, a std::vector<int>*. This is, because c-style arrays like vector<int> v[10000]; are just pointers. The number in the brackets just tells the compiler how much memory he should allocate on the stack to fulfill the memory requirements of this array.
So if you want to pass it to your function, you can do it in several ways. Replacing the vector<int> &vecvec[] with vector<int>* vecvec will probably be the fastest fix.
However, a more suitable solution to your problem is probably using a std::vector<std::vector<int>> v; like suggested the answer of "lenik", because you can resize it using v.resize(10000) and fetch the current size with v.size() (Always use this when looping over the vector elements) . You can pass it directly to your function using std::vector<std::vector<int>>&. Additionally, you don't need to pass num to your function if you resize your array to the number you entered:
...
cin >> n;
std::vector<std::vector<int>> v(n);
or
...
cin >> n;
std::vector<std::vector<int>> v;
v.resize(n);
Then your loops would be
for(int i=0; i < v.size(); i++){
...
for(int j=0; j < v.size(); j++){
...
}
...
}
Alternatively, if you know that your array of vectors always has a constant size, you can also use a std::array<std::vector<int>, 10000> v; (#include <array>). It is a wrapper class around the c-style array which gives you extra functionality like storing the array's size that you can get in the same way as in the std::vector(v.size()).
An additional note:
There is no need to pass num per reference int&. Fundamental types like int, float, double etc should always be passed by value and not per reference if you are not intending to modify their value inside the function.

Populating a two dimension static vector using C++98 standard

I have a two-dimensional static vector ( std::vector< std::vector<double> > ) which needs to be populated and I am working on an old project which requires to be compiled using C++98. Therefore, I am not allowed to use std::vector<...> v = { {1,2}, {3,4} }; syntax.
For unidimensional vectors, assigning an array as double a[] = {1,2}; and then using the std::vector<double> v(a, a+2) does the trick; however, it is not working for two dimensional vectors.
std::vector< std::vector<double> >
x1_step_lw_2(__x1_step_lw_2,
__x1_step_lw_2 + ARRAY_SIZE(__x1_step_lw_2));
I get the following error:
../src/energyConsumption/ue-eennlite-model-param-7IN-30NN.cpp:193:33: required from here
/usr/include/c++/4.8/bits/stl_construct.h:83:7: error: invalid conversion from ‘const double*’ to ‘std::vector<double>::size_type {aka long \
unsigned int}’ [-fpermissive]
::new(static_cast<void*>(__p)) _T1(__value);
(ARRAY_SIZE(x) is a macro which calculates the size of an array)
And since these vectors are attributes of the class, It would make no sense to initiate them on a constructor.
I am fighting against this problem for some time, and most of the 'solutions' involve to switch to C++11, which is not an option.
Any help is appreciated.
My C++98 is rusty, but something like this should work:
double a[] = { 1, 2 };
double b[] = { 3, 4 };
double c[] = { 5, 6 };
std::vector<double> v[] =
{
std::vector<double>(a, a + ARRAY_SIZE(a)),
std::vector<double>(b, b + ARRAY_SIZE(b)),
std::vector<double>(c, c + ARRAY_SIZE(c))
};
std::vector< std::vector<double> > vv(v, v + ARRAY_SIZE(v));
Try this:
#include <iostream>
#include <vector>
/**this generates a vector of T type of initial size N, of course it is upto you whether you want to use N or not, and returns the vector*/
template<class T>
std::vector<T> generateInitVecs(size_t N)
{
std::vector<T> returnable;
for(int i = 0; i < N; i++)
returnable.push_back(0);
return returnable;
}
int main()
{
std::vector< std::vector<double> > twoDvector;
/**Since twoDvector stores double type vectors it will be first populated by double type vectors*/
for(int i = 0; i < 10; i++){
twoDvector.push_back(generateInitVecs<double>(10));
}
/**populating the vector of vectors*/
for(int i = 0; i < 10; i++)
for(int j = 0; j < 10; j++){
/**can be treated as 2D array*/
twoDvector[i][j] = 50;
}
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
std::cout << twoDvector[i][j] << " ";
}
std::cout << "\n";
}
}
It will print a 10 x 10 matrix, with all values assigned 50.

Debug Assertion [Vector]

I'm wondering if something is wrong with my code especially the vector implementation?
Well,I was just exposed to the use of vector yesterday by people here.
In my college,I only learnt array.So,the usage of vector is kinda new to me.
To my understanding,vector is basically a dynamic array.-Correct me if I were wrong
Well,so lets go with my code.I got the following error: "Vector subscript out of range" after inputting n value.
EDIT:Fixed my earlier issue.Thanks to #quantdev .Now I noticed that my values aren't sorted.
#include<iostream>
#include<vector>
using namespace std;
//Function prototype
void Insertion_sort(vector<int> AR, int n);
void random_store(int val, vector<int> &aVec);
int main()
{
int nvalue;
vector<int> int_vector;
cout << "How many numbers would you like to generate?\n";
cin >> nvalue;//get input from user
random_store(nvalue, int_vector);//pass user input into random() function
system("pause");
return 0;
}
void random_store(int val, vector<int> &aVec)//store randomly generated value
{
int num;//represent random integer output
for (int i = 0; i < val; i++)
{
aVec.push_back(rand() % val + 1);//push each generated value into vector
}
Insertion_sort(aVec,val);//Pass the vector into a function to perform sorting
cout << " \n The sorted array is as follows \n ";
for (int i = 1; i <= val; i++)//Print sorted array
{
cout << " \n Element " << i << " : " << aVec[i] << endl;//will loop from aVec 1st array till n value
}
}
void Insertion_sort(vector<int> AR, int n)//insertion sort function
{
int j, val;//iterate through entire list
for (int i = 1; i < n; i++)
{
val = AR[i];
j = i - 1;
while (j >= 0 && AR[j] > val){
AR[j + 1] = AR[j];
j = j - 1;
}
AR[j + 1] = val;
}
} // end of insertion sort function
The problem is that your vector contains val values, so indexes are in [0, val-1], but within this loop :
for (int i = 1; i <= val; i++)
The last iteration will try to access the element at index val+1, which is out of bounds (it also misses the first element, at index 0)
Change it to :
for (int i = 0; i < val; i++)
And since indexes are of type std::size_t :
for (std::size_t i = 0; i < val; i++)
Note:
Your sort function takes a vector by value, sorting a copy of the vector. You probably want to pass by reference instead :
void Insertion_sort(vector<int>& AR, int n)