segmentation fault using nested vectors - c++

I stumbled upon the following code segment somewhere to create a list of random numbers in a certain interval:
#include <vector>
#include <iostream>
#include <math.h>
struct gen_rand_pos{
double factor;
public:
gen_rand_pos(double r=1.0): factor(r/RAND_MAX)
{}
double operator()(){
return rand()*factor;
}
};
int main(){
int N = 5;
std::vector<double> result(N);
std::generate_n(std::back_inserter(result), N, gen_rand_pos(1.0));
std::cout << result[0] << std::endl;
}
It works perfectly fine. I tried to take this one step further and do the same, but this time creating a list(vector) of random unit vectors, uniformly distributed on the sphere. Here is my go at this:
double l2_norm(std::vector<double> const& u) {
double accum = 0.;
for (double x : u) {
accum += x * x;
}
return sqrt(accum);
}
struct gen_rand_vec{
double factor;
public:
gen_rand_vec(): factor(2.0/RAND_MAX)
{}
std::vector<double> operator()(){
std::vector<double> result = {rand()*factor-1,rand()*factor-1,rand()*factor-1}; // uniform in each component
double norm = l2_norm(result);
std::transform(result.begin(), result.end(), result.begin(),
std::bind1st(std::multiplies<float>(),1/norm)); // normalize the vector
return result;
}
};
However if I now try to construct it in the same manner:
int main(){
int N = 5;
std::vector<std::vector<double>> result2(N);
std::generate_n(std::back_inserter(result2), N, gen_rand_vec());
std::cout << result2[0][0] <<std::endl;
}
I get a segmentation error. Is the problem lying in the back_inserter or am I doing something completely wrong? I can't figure out. I checked the construction of the single vectors and they work just fine, so the mistake has to lie somewhere after that.
Thanks in advance.

Default size of inner vectors for result2 for indices <0,4> is 0, so you cannot access
result2[0][0] // inner vector doesn't keep any elements
when you call generate_n with back_inserter, you add new vectors to the end of result2. In this case you can access indices of inner vector for result2[>=5].

Your problem is quite simple, std::back_inserter is inserting new vectors at the end of result2. Hence, you cannot access the first element, since it is not initialized. To solve this, just remove the (N) from the initialization of result2. Example.

Related

How to pass array 2d as parameter from function and return array 2d this function?

The problem in question involves an iterative process in which the object "am" changes with this process (loop). So, I need to create a "res" object that will store the results of the Tfunc function to be used in the same process in another procedure. However, I can not do that. I'm a good beginner in C ++ programming. I'm a programmer in the R language.
My operational system is ubuntu 16.04 using ide codeblocks.
#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
const int k = 3;
double Tfunc(double Told[k][k], double amm, int K);
int sample(int x);
int main(){
int i, j;
double am = 50;
double told[k][k]{
{1,0,0},
{0,1,0},
{0,0,1}
};
double res;
res = Tfunc(told, am, k);
for(i=0;i<k;i++){
for(j=0;j<k;j++){
cout << res[i][j] << " ";
}
cout << "\n";
}
return 0;
}
double Tfunc(double Told[k][k], double amm, int K)
{
int id1;
int id2;
int id3;
id1 = sample(K);
id2 = sample(K);
id3 = sample(K);
while(id2 == id3){
id3 = sample(K);
}
Told[id1][id2] = Told[id1][id2] + amm;
Told[id1][id3] = Told[id1][id3] - amm;
return Told;
}
int sample(int x)
{
srand(time(NULL)); //initialize the random seed
int RandIndex = rand() % (x);
return RandIndex;
}
First of all, and, maybe this is one of the root causes of your problem, you are not passing the 2 dimensional array to your subfunction correctly.
You could pass it as reference or as pointer. Then you could also modify the array, given as parameter, in your subfunction.
Please read here
Then, in modern C++ you would use STL containers for your puposes. And for 2 dimensional stuff, you need to create a container of containers. So a std::vector of std::vector, or a std::array of std::array.
The Tfunc will return that container-container and make usage of RVO (Return Value Optimization). So there is no loss in complexity.
I created an example file for you. This is just one possible solution. There are many.
#include <iostream>
#include <random>
#include <iterator>
#include <algorithm>
#include <array>
constexpr size_t MatrixDimension = 3;
using DoubleArray = std::array<double, MatrixDimension>;
using Matrix = std::array<DoubleArray, MatrixDimension>;
constexpr Matrix StartMatrix{{
{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}
}};
size_t randomIndex()
{
std::random_device randomDevice; // Obtain a random number from hardware
std::mt19937 randomGenerator(randomDevice()); // Seed the generator
std::uniform_int_distribution<size_t> distribution(0, MatrixDimension-1); // Range
return distribution(randomGenerator);
}
Matrix Tfunc(const Matrix& givenMatrix, double amm)
{
size_t index1{ randomIndex() }; // Set indices with random values
size_t index2{ randomIndex() };
size_t index3{ randomIndex() };
while (index2 == index3) { // Make sure that index 2 is not equal index 3
index3 = randomIndex();
}
Matrix calculatedMatrix{};
calculatedMatrix[index1][index2] = givenMatrix[index1][index2] + amm;
calculatedMatrix[index1][index3] = givenMatrix[index1][index3] - amm;
return calculatedMatrix;
}
int main()
{
constexpr double amm{ 50.0 };
Matrix result = Tfunc(StartMatrix, amm); // Apply Tfunc to matrix
// Debug Output. Print matrix to std::cout
std::for_each(result.begin(), result.end(), [](DoubleArray &da) {std::copy(da.begin(), da.end(), std::ostream_iterator<double>(std::cout, " ")); std::cout << '\n'; });
return 0;
}
BTW. I do not know the purpose of your program. But I think you want to have 3 different indices in TFunc. This is not guaranteed. 2 can be the same.
I hope this helps . . .

How to calculate sin and cos off all vector elements?

My code
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <sstream>
#include <cmath>
#define PI 3.14159265
int main(){
std::ifstream ifs("MFSO7.dat");
std::string line;
std::vector<float> column1;
std::vector<float> column2;
std::vector<float> column3;
std::vector<float> vkos;
std::vector<float> vsin;
while(std::getline(ifs, line)) // read one line from ifs
{
std::istringstream iss(line); // access line as a stream
float item1;
float item2;
float item3;
// Read the items from the line
iss >> item1 >> item2 >> item3;
// Add them to the columns.
column1.push_back(item1);
column2.push_back(item2);
column3.push_back(item3);
}
for(int i=0;i<38;i++)
{
vkos[i]=cos(column3[i]* PI/180.0 );
vsin[i]=sin(column3[i]* PI/180.0 );
}
std::cout << vkos[1] << std::endl;
}
Whem I execute the code I got
milenko#milenko-X58-USB3:~/Calibration Files$ ./a1
Segmentation fault (core dumped)
Why?May be I should avoid the loop or...?
A vector will have some capacity to hold new items. This is different from size, the count of elements that are actually in the vector. Thus a capacity of n that does not mean that it already has n items. A vector would have no items when it just got constructed by the default constructor -- the one with no arguments.
Referring to the ith element via vector::operator[] is incorrect when i >= n, where n is the size; in your case n is 0. So first you create them by vkos.push_back(cos(value)) instead of directly assigning to the index. On every push_back, the vector's size increases by one.
for(auto angle : column3)
{
vkos.push_back(cos(angle * PI/180.0));
vsin.push_back(sin(angle * PI/180.0));
}
if (vkos.size() >= 2)
cout << vkos[1] << '\n';
std::valarray is made for that, sin is overloaded with valarray:
vkos = cos(column3 * PI/180.0);
vsin = sin(column3 * PI/180.0);
No need for a loop, that would work.
If you insist on iterating with an index into a vector, you can use:
for (int i = 0; i < column3.size(); ++i) ...
This way, you will at least not try to access at an index that is larger than the current number or elements + 1.
Otherwise, you can try to initialize the vector to have exactly that many values:
std::vector<float> column3(38, 0);
Or if you are using C++11 you could even go for the
for (auto x : column3) ...
The problem is you are trying to assign to memory you don't have. Why don't you use std::transform? Using standard algorithms will help avoid these types of bugs, can often perform better than hand written loops, and most importantly is easier to read & understand. Also, avoid using #define, prefer constexpr.
constexpr double Pi {3.14159265};
constexpr auto PiDiv180 = Pi / 180;
std::transform(std::cbegin(column3), std::cend(column3), std::back_inserter(vkos),
[PiDiv180] (const auto v) { return std::cos(v * PiDiv180); });
std::transform(std::cbegin(column3), std::cend(column3), std::back_inserter(vsin),
[PiDiv180] (const auto v) { return std::sin(v * PiDiv180); });
It's because you're assigning to elements of vkos and vsin that haven't been constructed yet.
It's best to stick to the STL for these types of loop-based tasks, a lot of errors are taken care of for you. For this particular problem, you're looking for std::transform. The following code has zero overhead compared to your accepted solution:
std::vector<std::pair<float, float>> vkossin{};
std::transform(
std::begin(column3), std::end(column3), std::back_inserter(vkossin),
[](float degs) {
float rads = degs*PI/180.0;
return std::make_pair(cos(rads), sin(rads));
});
std::cout << vkossin[1].first << '\n';
std::back_inserter, std::pair, std::make_pair

Computing the scalar product of two vectors in C++

I am trying to write a program with a function double_product(vector<double> a, vector<double> b) that computes the scalar product of two vectors. The scalar product is
$a_{0}b_{0}+a_{1}b_{1}+...+a_{n-1}b_{n-1}$.
Here is what I have. It is a mess, but I am trying!
#include <iostream>
#include <vector>
using namespace std;
class Scalar_product
{
public:
Scalar_product(vector<double> a, vector<double> b);
};
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
int main() {
cout << product << endl;
return 0;
}
Unless you need to do this on your own (e.g., writing it is homework), you should really use the standard algorithm that's already written to do exactly what you want:
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<double> a {1, 2, 3};
std::vector<double> b {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(std::begin(a), std::end(a), std::begin(b), 0.0);
return 0;
}
Note that while begin(a) and end(a) are new in C++11, std::inner_product has been available since C++98. If you are using C++ 98 (or 03), it's pretty easy to write your own equivalent of begin and end to work with arrays though:
template <class T, size_t N>
T *begin(T (&array)[N]) {
return array;
}
template <class T, size_t N>
T *end(T (&array)[N]) {
return array + N;
}
Using these, a C++ 98 version of the previous code could look something like this:
int main() {
double a[] = {1, 2, 3};
double b[] = {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(begin(a), end(a), begin(b), 0.0);
return 0;
}
Note that the begin and end above will only work for arrays, where the begin and end in C++11 (and later) will also work for normal collection types that define a .begin() and .end() (though it's trivial to add overloads to handle those as well, of course):
template <class Coll>
typename Coll::iterator begin(Coll const& c) { return c.begin(); }
template <class Coll>
typename Coll::iterator end(Coll const& c) { return c.end(); }
You can delete the class you have defined. You don't need it.
In your scalar_product function:
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
It's almost there. You don't need 2 loops. Just one.
double scalar_product(vector<double> a, vector<double> b)
{
if( a.size() != b.size() ) // error check
{
puts( "Error a's size not equal to b's size" ) ;
return -1 ; // not defined
}
// compute
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
product += (a[i])*(b[i]); // += means add to product
return product;
}
Now to call this function, you need to create 2 vector objects in your main(), fill them with values, (the same number of values of course!) and then call scalar_product( first_vector_that_you_create, second_vector_object );
While you have been presented many solutions that work, let me spin up another variation to introduce a couple of concepts that should help you writing better code:
class are only needed to pack data together
a function should check its preconditions as soon as possible, those should be documented
a function should have postconditions, those should be documented
code reuse is the cornerstone of maintenable programs
With that in mind:
// Takes two vectors of the same size and computes their scalar product
// Returns a positive value
double scalar_product(std::vector<double> const& a, std::vector<double> const& b)
{
if (a.size() != b.size()) { throw std::runtime_error("different sizes"); }
return std::inner_product(a.begin(), a.end(), b.begin(), 0.0);
} // scalar_product
You could decide to use the inner_product algorithm directly but let's face it:
it requires four arguments, not two
it does not check for its arguments being of the same size
so it's better to wrap it.
Note: I used const& to indicate to the compiler not to copy the vectors.
You seem to want to make a class specifically for vectors. The class I made in my example is tailored to 3 dimensional vectors, but you can change it to another if desired. The class holds i,j,k but also can conduct a scalar products based on other MathVectors. The other vector is passed in via a C++ reference. It is hard to deduce what the question was, but I think this might answer it.
#include <iostream>
using namespace std;
class MathVector
{
private:
double i,j,k;
public:
MathVector(double i,double j,double k)
{
this->i=i;
this->j=j;
this->k=k;
}
double getI(){return i;}
double getJ(){return j;}
double getK(){return k;}
double scalar(MathVector &other)
{
return (i*other.getI())+(j*other.getJ())+(k*other.getK());
}
};
int main(int argc, char **argv)
{
MathVector a(1,2,5), b(2,4,1);
cout << a.scalar(b) << endl;
return 0;
}
Here is the code that you should have. I see you have used class in your code, which you do not really need here. Let me know if the question required you to use class.
As you are new and this code might scare you. So, I will try to explain this as I go. Look for comments in the code to understand what is being done and ask if you do not understand.
//Scalar.cpp
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
/**
This function returns the scalar product of two vectors "a" and "b"
*/
double scalar_product(vector<double> a, vector<double> b)
{
//In C++, you should declare every variable before you use it. So, you declare product and initialize it to 0.
double product = 0;
//Here you check whether the two vectors are of equal size. If they are not then the vectors cannot be multiplied for scalar product.
if(a.size()!=b.size()){
cout << "Vectors are not of the same size and hence the scalar product cannot be calculated" << endl;
return -1; //Note: This -1 is not the answer, but just a number indicating that the product is not possible. Some pair of vectors might actually have a -1, but in that case you will not see the error above.
}
//you loop through the vectors. As bobo also pointed you do not need two loops.
for (int i = 0; i < a.size(); i++)
{
product = product + a[i]*b[i];
}
//finally you return the product
return product;
}
//This is your main function that will be executed before anything else.
int main() {
//you declare two vectors "veca" and "vecb" of length 2 each
vector<double> veca(2);
vector<double> vecb(2);
//put some random values into the vectors
veca[0] = 1.5;
veca[1] = .7;
vecb[0] = 1.0;
vecb[1] = .7;
//This is important! You called the function you just defined above with the two parameters as "veca" and "vecb". I hope this cout is simple!
cout << scalar_product(veca,vecb) << endl;
}
If you are using an IDE then just compile and run. If you are using command-line on a Unix-based system with g++ compiler, this is what you will do (where Scalar.cpp is the file containing code):
g++ Scalar.cpp -o scalar
To run it simply type
./scalar
You should get 1.99 as the output of the above program.

Best way to split a vector into two smaller arrays?

What I'm trying to do:
I am trying to split a vector into two separate arrays. The current int vector contains an element per line in a text file. The text file is a list of random integers.
How I'm planning to do it:
My current idea is to create two regular int arrays, then iterate over the entire vector and copy n/2 elements to each of the arrays.
What I would like to know:
What is the most elegant way of accomplishing my task? I have a feeling that I can do this without iterating over the vector multiple times.
Code:
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
using namespace std;
vector<int> ifstream_lines(ifstream& fs)
{
vector<int> out;
int temp;
while(fs >> temp)
{
out.push_back(temp);
}
return out;
}
vector<int> MergeSort(vector<int>& lines)
{
int split = lines.size() / 2;
int arrayA[split];
int arrayB[split];
}
int main(void)
{
ifstream fs("textfile.txt");
vector<int> lines;
lines = ifstream_lines(fs);
return 0;
}
Thank you :)
Use iterators.
std::vector<int> lines;
// fill
std::size_t const half_size = lines.size() / 2;
std::vector<int> split_lo(lines.begin(), lines.begin() + half_size);
std::vector<int> split_hi(lines.begin() + half_size, lines.end());
Since iterator ranges represent half open ranges [begin, end), you don't need to add 1 to the second begin iterator: lines.begin() + half_size isn't copied to the first vector.
Note that things like
int split = lines.size() / 2;
int arrayA[split];
int arrayB[split];
Are not standard C++ (and as such not portable). These are so-called variable-length arrays (VLAs for short) and are a C99 thing. Some compilers have them as an extension while compiling C++ code (GCC, Clang). Always compile with -pedantic to get a warning. These VLAs act funky for non-POD types and aren't generally useful, since you can't even return them.
If you can't use code from Xeo answer due to strict compiler rules or you want more generic way, try std::advance:
#include <vector>
#include <iterator>
size_t middle = input.size()/2;
std::vector<int>::const_iterator middleIter(input.cbegin());
std::advance(middleIter, middle);
std::vector<int> leftHalf(input.begin(), middleIter);
std::vector<int> rightHalf(middleIter, input.end());
If you only need a reference to the numbers without manipulating them, then you can do:
int *array_1 = &lines[0];
int *array_2 = &lines[lines.size() / 2];
array_1 and array_2 are, actually, pointers to the start and middle of the vector. This works since STL guarantees that vectors store their elements within a continuous memory.
Note that referring to lines.begin() can't be used for this.
Solution to split vector to variable count parts using iterator.
#include <iostream>
#include <vector>
int main()
{
// Original vector of data
std::vector<double> mainVec{1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0};
// Result vectors
std::vector<std::vector<double>> subVecs{};
// Start iterator
auto itr = mainVec.begin();
// Variable to control size of non divided elements
unsigned fullSize = mainVec.size();
// To regulate count of parts
unsigned partsCount = 4U;
for(unsigned i = 0; i < partsCount; ++i)
{
// Variable controls the size of a part
auto partSize = fullSize / (partsCount - i);
fullSize -= partSize;
//
subVecs.emplace_back(std::vector<double>{itr, itr+partSize});
itr += partSize;
}
// Print out result
for (const auto& elemOuter : subVecs)
{
std::cout << std::fixed;
for (const auto& elemInner : elemOuter)
{
std::cout << elemInner << " ";
}
std::cout << "\n";
}
}

C++ sort on vector using function object

I'm trying to sort a vector v1 using another vector v2. I can't wrap my head around this error:
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check
Abort trap
while running this code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Comp
{
public:
Comp(vector<double>& inVec): _V(inVec) {}
bool operator()(int i, int j) {return (_V.at(i)<_V.at(j));}
private:
vector<double> _V;
};
int main(int argc, char** argv)
{
double x1[] = {90.0, 100.0, 80.0};
double x2[] = {9.0, 3.0, 1.0};
vector<double> v1(x1,x1+3);
vector<double> v2(x2,x2+3);
sort(v1.begin(), v1.end(), Comp(v2)); // sort v1 according to v2
for(unsigned int i=0; i<v1.size(); i++)
{
cout << v1.at(i) << " " << v2.at(i) << endl;
}
return 0;
}
v1 and v2 are of the same size. Why the out_of_range error?
Thanks in advance for any pointers.
I believe that your problem is in this line:
bool operator()(int i, int j) {return (_V.at(i)<_V.at(j));}
The problem is that when the std::sort algorithm uses a custom callback, it passes in the actual values stored in the vector at particular locations, not the indices of those locations within the vector. As a result, when you call
sort(v1.begin(), v1.end(), Comp(v2)); // sort v1 according to v2
The Comp comparator you've written will be getting passed as parameters the values stored in the v1 vector and will then try indexing at those positions into the v2 vector. Since the values in v1 are larger than the size of v2, the call to _V.at(i) will cause an out_of_range exception to be thrown.
If you want to sort the two ranges with respect to one another, you'll need to adopt a different approach. I'm not aware of a straightforward way of doing this, but I'll let you know if I think of one.
Size of v1 is just 3, but you're using each value of v2 as index of v1. And as v2 has one value 9 which is greater than the size of v1, that is what gives std::out_of_range error in here:
bool operator()(int i, int j) {return (_V.at(i)<_V.at(j));}
std::vector::at function gives std::out_of_range exception of the index passed to it as argument is greater than the size of vector. That is, the index must be less than vector::size().
Ok, now you're probably aware of the fact, that i and j are actual values held in vector rather than indices. There is a good reason for that: sorting is all about values, not indexes. Note you're passing iterators to sort method, so there is no way it can extract index for you. Of course, you could get index relative to first iterator, but there is no reason for doing this.
However, let's be insane for awhile and imagine you would get indices rather than values in your comparator. Assume that your code does what you want and let's think about following scenario:
v1 = {20,10}; v2 = {2,1}
I secretly assume you want the following output:
v1 = {10, 20}
right? Now imagine I'm a sorting function you're calling and I do following steps:
v2[0] < v2[1] is false, so swap(&v1[0], &v1[1])
It's sorted, isn't it? But wait, I'm a crazy sorting function, so I want to make sure it's sorted, so I do the following:
v2[0] < v2[1] is false, swap(&v1[0], &v1[1])
And again:
v2[0] < v2[1] is false, swap(&v1[0], &v1[1])
and again, again, again...
Can you see a problem? Sorting function has some requirements and for sure you're breaking fundamental one.
I suspect you need completely different container (maybe std::map with keys from vec1 and values from vec2) or at least something like vector< pair<double, double> >, so you can easily sort by either first or second value. If not, consider creating vector with values in range [0, v2.size()), sorting it using your comparator (values are equal to indices, so will be all right) and then print correct values from v1. This code works fine:
vector<size_t> indices;
for(size_t i =0; i < v1.size(); ++i)
{
indices.push_back(i);
}
// yes, it works using your original comparator
sort(indices.begin(), indices.end(), Comp(v2));
for(size_t i =0; i < indices.size(); ++i)
{
cout << v1.at(indices[i]) << " " << v2.at(indices[i]) << endl;
}
Like said in other answers, the problem is that the sort algorithm passes the actual values to compare rather than indices.
Here is how you can solve it:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<double, double> Zipped; // Represent an element of two lists
// "zipped" together
// Compare the second values of two pairs
bool compareSeconds ( Zipped i, Zipped j )
{
return i.second < j.second;
}
int main ( int argc, char **argv )
{
double x1[] = { 90, 100, 80 };
double x2[] = { 9, 3, 1 };
vector<double> v1(x1, x1 + 3);
vector<double> v2(x2, x2 + 3);
vector<Zipped> zipped(v1.size()); // This will be the zipped form of v1
// and v2
for ( int i = 0; i < zipped.size(); ++i )
{
zipped[i] = Zipped(v1[i], v2[i]);
}
sort(zipped.begin(), zipped.end(), &compareSeconds);
for ( int i = 0; i < zipped.size(); ++i )
{
cout << zipped[i].first << " " << zipped[i].second << endl;
}
for ( int i = 0; i < v1.size(); ++i )
{
v1[i] = zipped[i].first;
}
// At this point, v1 is sorted according to v2
return 0;
}