modifying a container outside function

G

Gary Wessle

Hi

I wrote a routine which takes 4 arguments, first a file-name, a text file which has 2
columns of doubles. second and third is a pointer to valarray<double>,
the forth is an int. if the int is true, it give 1/data-read.
it compiled but and ran but did not produce the side effect I want.

thanks for you time.


#include <string>
using std::string;
#include <vector>
using std::vector;
#include <valarray>
using std::valarray;
#include <iostream>
using std::cout;
#include <fstream>
using std::ifstream;
#include <sstream>
using std::stringstream;


void get_data(string, valarray<double>*, valarray<double>* , int x=0);

void get_data(string file, valarray<double>* a,
valarray<double>* b, int x){
ifstream in(file.c_str());
string line;
vector<double> va, vb;
while( getline(in, line) ){
stringstream input(line.c_str() );
double num1, num2;
while( input >> num1 >> num2 ){
va.push_back(num1);
vb.push_back(num2);
}
}
(*a).resize( va.size() );
(*b).resize( vb.size() );
if(x){
valarray<double> tmp1(va.size());
valarray<double> tmp2(vb.size());
copy( va.begin(), va.end(), &tmp1[0] );
copy( vb.begin(), vb.end(), &tmp2[0] );
(*a) = 1.0 / tmp1;
(*b) = 1.0 / tmp2;
} else {
copy( va.begin(), va.end(), a ); //<------------- here
copy( vb.begin(), vb.end(), b ); //<--------------here
}
}

the lines
****************
copy( va.begin(), va.end(), a );
copy( vb.begin(), vb.end(), b );
****************
caused a segmentation fault.
am I not taking the start of the container which needs to be populated
by using the pointer to it, which is a and b and the sizes are set
correctly, then why the seg faults?



int main(){
valarray<double> aa, bb;
get_data(filename, &aa, &bb, 1);
}
 
T

Thomas Tutone

Gary said:
Hi

I wrote a routine which takes 4 arguments, first a file-name, a text file which has 2
columns of doubles. second and third is a pointer to valarray<double>,
the forth is an int. if the int is true, it give 1/data-read.
it compiled but and ran but did not produce the side effect I want.

thanks for you time.


#include <string>
using std::string;
#include <vector>
using std::vector;
#include <valarray>
using std::valarray;
#include <iostream>
using std::cout;
#include <fstream>
using std::ifstream;
#include <sstream>
using std::stringstream;


void get_data(string, valarray<double>*, valarray<double>* , int x=0);

void get_data(string file, valarray<double>* a,
valarray<double>* b, int x){
ifstream in(file.c_str());
string line;
vector<double> va, vb;
while( getline(in, line) ){
stringstream input(line.c_str() );
double num1, num2;
while( input >> num1 >> num2 ){
va.push_back(num1);
vb.push_back(num2);
}
}
(*a).resize( va.size() );
(*b).resize( vb.size() );
if(x){
valarray<double> tmp1(va.size());
valarray<double> tmp2(vb.size());
copy( va.begin(), va.end(), &tmp1[0] );
copy( vb.begin(), vb.end(), &tmp2[0] );
(*a) = 1.0 / tmp1;
(*b) = 1.0 / tmp2;
} else {
copy( va.begin(), va.end(), a ); //<------------- here
copy( vb.begin(), vb.end(), b ); //<--------------here

There's got to be a better way to do this, but don't you mean:

copy(va.begin(), va.end(), &((*a)[0]));
copy(vb.begin(), vb.end(), &((*b)[0]));

After all, in other words, I think you have inappropriately assumed
that a pointer to a valarray is the same as a pointer to the first
element of the valarray. What makes you think that? (That's a real
question - it may well be that you know something about valarrays that
I don't.) Anyway, I suspect that that is the source of your segfault.

Best regards,

Tom
 
G

Gary Wessle

Gary Wessle said:
Hi

I wrote a routine which takes 4 arguments, first a file-name, a text file which has 2
columns of doubles. second and third is a pointer to valarray<double>,
the forth is an int. if the int is true, it give 1/data-read.
it compiled but and ran but did not produce the side effect I want.

thanks for you time.


#include <string>
using std::string;
#include <vector>
using std::vector;
#include <valarray>
using std::valarray;
#include <iostream>
using std::cout;
#include <fstream>
using std::ifstream;
#include <sstream>
using std::stringstream;


void get_data(string, valarray<double>*, valarray<double>* , int x=0);

void get_data(string file, valarray<double>* a,
valarray<double>* b, int x){
ifstream in(file.c_str());
string line;
vector<double> va, vb;
while( getline(in, line) ){
stringstream input(line.c_str() );
double num1, num2;
while( input >> num1 >> num2 ){
va.push_back(num1);
vb.push_back(num2);
}
}
(*a).resize( va.size() );
(*b).resize( vb.size() );
if(x){
valarray<double> tmp1(va.size());
valarray<double> tmp2(vb.size());
copy( va.begin(), va.end(), &tmp1[0] );
copy( vb.begin(), vb.end(), &tmp2[0] );
(*a) = 1.0 / tmp1;
(*b) = 1.0 / tmp2;
} else {
copy( va.begin(), va.end(), a ); //<------------- here
copy( vb.begin(), vb.end(), b ); //<--------------here
}
}

the lines
****************
copy( va.begin(), va.end(), a );
copy( vb.begin(), vb.end(), b );
****************
caused a segmentation fault.
am I not taking the start of the container which needs to be populated
by using the pointer to it, which is a and b and the sizes are set
correctly, then why the seg faults?



int main(){
valarray<double> aa, bb;
get_data(filename, &aa, &bb, 1);
}


Comment from samj
Date: 08/18/2006 04:30PM PDT
Your Comment

the problem fixed:

here is what I did


void fxpair::get_data(string file, valarray<double>* a,
valarray<double>* b, int x){
ifstream in(file.c_str());
string line;
vector<double> va, vb;
while( getline(in, line) ){
stringstream input(line.c_str() );
double num1, num2;
while( input >> num1 >> num2 ){
va.push_back(num1);
vb.push_back(num2);
}
}
(*a).resize( va.size() );
(*b).resize( vb.size() );
valarray<double> t1(va.size());
valarray<double> t2(vb.size());
copy( va.begin(), va.end(), &t1[0] );
copy( vb.begin(), vb.end(), &t2[0] );
if(x){
(*a) = 1.0 / t1;
(*b) = 1.0 / t2;
} else {
(*a) = t1;
(*b) = t2;
}
}

here again after changing the version so it uses refrence instead of pointers.
no it works fine.

void fxpair::get_data(string file, valarray<double>& a,
valarray<double>& b, int x){
ifstream in(file.c_str());
string line;
vector<double> va, vb;
while( getline(in, line) ){
stringstream input(line.c_str() );
double num1, num2;
while( input >> num1 >> num2 ){
va.push_back(num1);
vb.push_back(num2);
}
}
a.resize( va.size() );
b.resize( vb.size() );
valarray<double> t1(va.size());
valarray<double> t2(vb.size());
copy( va.begin(), va.end(), &t1[0] );
copy( vb.begin(), vb.end(), &t2[0] );
if(x){
a = 1.0 / t1;
b = 1.0 / t2;
} else {
a = t1;
b = t2;
}
}

and to be called like this
valarray<double> a1, b1;
get_data(file1, a1, b1);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,273
Latest member
DamonShoem

Latest Threads

Top