how to best use valarrays as constructor arguments

G

Gerard Kramer

Presently I have some difficulties with the following type of code which
is understandably causing a segfault:

//---- begin code ----

#include <valarray>
#include <iostream>


using namespace std;


class SomeClass {

private:
valarray <double> mx;

public:
SomeClass(valarray <double>& x) {mx = x;}
void func() {cout << mx[1];} // <---- Segfault here.

};


int main () {
valarray <double> x(5,10);
SomeClass foo(x);

foo.func();

return 0;
}

//---- end code ----

It will fail at runtime because, as I understand it, mx is a zero-size
valarray and hence mx[1] does not exist.

Yet (for a simple numerical code) I would like something similar to the
above to work, i.e. I'd like to pass a valarray of predefined size to
the constructor of a class to initialize a class-member valarray, say
mx, and after reference to mx's elements as mx[0], mx[1] etc. As a C++
starter I'm confused about the best way to work around the problem in
the code above. Any advice would be welcome.

Regards,
Gerard.
 
V

Victor Bazarov

Gerard said:
Presently I have some difficulties with the following type of code
which is understandably causing a segfault:

//---- begin code ----

#include <valarray>
#include <iostream>


using namespace std;


class SomeClass {

private:
valarray <double> mx;

public:
SomeClass(valarray <double>& x) {mx = x;}
void func() {cout << mx[1];} // <---- Segfault here.
Really?!!


};


int main () {
valarray <double> x(5,10);
SomeClass foo(x);

foo.func();

return 0;
}

//---- end code ----

It will fail at runtime because, as I understand it, mx is a zero-size
valarray and hence mx[1] does not exist.

It *will* fail or it *does* fail?

With the exception of using assignment instead of initialisation and some
superfluousness and extraneous whitespace, your code is fine, AFAICT.
Yet (for a simple numerical code) I would like something similar to
the above to work, i.e. I'd like to pass a valarray of predefined
size to the constructor of a class to initialize a class-member
valarray, say mx, and after reference to mx's elements as mx[0],
mx[1] etc. As a C++ starter I'm confused about the best way to work
around the problem in the code above. Any advice would be welcome.

What problem? Prove to us there is a problem, post the results of your
run, not your speculations. Step through it in a debugger. Print out
the *size* of 'mx' instead of its element. Anyway, do something, don't
just stand there.

V
 
G

Gerard Kramer

Victor said:
Gerard said:
Presently I have some difficulties with the following type of code
which is understandably causing a segfault:

//---- begin code ----

#include <valarray>
#include <iostream>


using namespace std;


class SomeClass {

private:
valarray <double> mx;

public:
SomeClass(valarray <double>& x) {mx = x;}
void func() {cout << mx[1];} // <---- Segfault here.

Really?!!

yes ;-)
};


int main () {
valarray <double> x(5,10);
SomeClass foo(x);

foo.func();

return 0;
}

//---- end code ----

It will fail at runtime because, as I understand it, mx is a zero-size
valarray and hence mx[1] does not exist.

It *will* fail or it *does* fail?

It *will* fail (by looking at the code) and so it *does* (by compiling
and running it.)
With the exception of using assignment instead of initialisation and some
superfluousness and extraneous whitespace, your code is fine, AFAICT.
Yet (for a simple numerical code) I would like something similar to
the above to work, i.e. I'd like to pass a valarray of predefined
size to the constructor of a class to initialize a class-member
valarray, say mx, and after reference to mx's elements as mx[0],
mx[1] etc. As a C++ starter I'm confused about the best way to work
around the problem in the code above. Any advice would be welcome.

What problem? Prove to us there is a problem, post the results of your
run, not your speculations. Step through it in a debugger. Print out
the *size* of 'mx' instead of its element. Anyway, do something, don't
just stand there.

I'm sorry? Well, thanks for the reply. As far as I can see I didn't
speculate about anything. Just to be clear: There is no problem, but I'd
like to learn how to get a certain thing done, namely:

The best way to somehow to use a valarray <double> as an argument of a
class constructor to initialize a class member variable of type valarray
<double>.

I can't see how to do that.

That's all. I'm sorry in case that bothered you. Won't happen again.
 
R

Richard Herring

I'd recommend making this take a const reference, but it shouldn't make
any difference to the rest of the code.

.... and I'd recommend using an initializer list, but again it shouldn't
make any difference.

: mx(x) {}
void func() {cout << mx[1];} // <---- Segfault here.

.... and this really ought to be a const member function, but again it
shouldn't matter.
Really?!!

yes ;-)
};


int main () {
valarray <double> x(5,10);
SomeClass foo(x);

foo.func();

return 0;
}

//---- end code ----

It will fail at runtime because, as I understand it, mx is a zero-size
valarray and hence mx[1] does not exist.

It *will* fail or it *does* fail?

It *will* fail (by looking at the code)

Can you describe, line by line, what you think the code is doing?
and so it *does* (by compiling
and running it.)
With the exception of using assignment instead of initialisation and some
superfluousness and extraneous whitespace, your code is fine, AFAICT.
Yet (for a simple numerical code) I would like something similar to
the above to work, i.e. I'd like to pass a valarray of predefined
size to the constructor of a class to initialize a class-member
valarray, say mx, and after reference to mx's elements as mx[0],
mx[1] etc. As a C++ starter I'm confused about the best way to work
around the problem in the code above. Any advice would be welcome.

What problem? Prove to us there is a problem, post the results of your
run, not your speculations. Step through it in a debugger. Print out
the *size* of 'mx' instead of its element. Anyway, do something, don't
just stand there.

I'm sorry? Well, thanks for the reply. As far as I can see I didn't
speculate about anything. Just to be clear: There is no problem, but I'd
like to learn how to get a certain thing done, namely:

The best way to somehow to use a valarray <double> as an argument of a
class constructor to initialize a class member variable of type valarray
<double>.
 
T

Tom Widmer

Gerard said:
Presently I have some difficulties with the following type of code which
is understandably causing a segfault:

//---- begin code ----

#include <valarray>
#include <iostream>


using namespace std;


class SomeClass {

private:
valarray <double> mx;

public:
SomeClass(valarray <double>& x) {mx = x;}

The above has undefined behaviour. Once you enter the constructor, mx
has size 0, but you are assigning to it a valarray of size != 0, which
isn't allowed. I think you meant:

SomeClass(valarray said:
void func() {cout << mx[1];} // <---- Segfault here.

With that change, no segfault will happen.
};


int main () {
valarray <double> x(5,10);
SomeClass foo(x);

foo.func();

return 0;
}

//---- end code ----

It will fail at runtime because, as I understand it, mx is a zero-size
valarray and hence mx[1] does not exist.

Well, the bug occurs before func() is even called.
Yet (for a simple numerical code) I would like something similar to the
above to work, i.e. I'd like to pass a valarray of predefined size to
the constructor of a class to initialize a class-member valarray, say
mx, and after reference to mx's elements as mx[0], mx[1] etc. As a C++
starter I'm confused about the best way to work around the problem in
the code above. Any advice would be welcome.

Just copy the valarray, rather than assigning it. If you must assign,
manually set the size first:
SomeClass(valarray <double> const& x) {
mx.resize(x.size());
mx = x;
}

As a general rule, avoid valarray entirely. There are far superior
maths libraries out there, such as boost::ublas or blitz++.

Tom
 
V

Victor Bazarov

Gerard said:
Victor said:
Gerard said:
Presently I have some difficulties with the following type of code
which is understandably causing a segfault:
[..]

It will fail at runtime because, as I understand it, mx is a
zero-size valarray and hence mx[1] does not exist.

It *will* fail or it *does* fail?

It *will* fail (by looking at the code) and so it *does* (by compiling
and running it.)

The reason I asked was that I took your code, compiled it and ran it,
and it ran fine on VC++ 2005.
With the exception of using assignment instead of initialisation and
some superfluousness and extraneous whitespace, your code is fine,
AFAICT.
Yet (for a simple numerical code) I would like something similar to
the above to work, i.e. I'd like to pass a valarray of predefined
size to the constructor of a class to initialize a class-member
valarray, say mx, and after reference to mx's elements as mx[0],
mx[1] etc. As a C++ starter I'm confused about the best way to work
around the problem in the code above. Any advice would be welcome.

What problem? Prove to us there is a problem, post the results of
your run, not your speculations. Step through it in a debugger.
Print out the *size* of 'mx' instead of its element. Anyway, do
something, don't just stand there.

I'm sorry? Well, thanks for the reply. As far as I can see I didn't
speculate about anything.

You said "it will fail". Any statement about the future is speculation
by definition. Don't take offence, it just is.

Then you said 'mx is a zero-size valarray'. Have you actually looked?
Have you tried running it under a debugger? Have you tried printing out
the size of the 'mx' valarray?
Just to be clear: There is no problem, but

I am sorry. No problem?
I'd like to learn how to get a certain thing done, namely:

The best way to somehow to use a valarray <double> as an argument of a
class constructor to initialize a class member variable of type
valarray <double>.

I can't see how to do that.

But you *did* that. Aside from small things that don't matter in this
particular case, your code is [supposed to be] working.
That's all. I'm sorry in case that bothered you. Won't happen again.

Nothing bothered me. Nothing to apologise for. You made some statements
that prompted me to ask more questions. Just answer them.

V
 
V

Victor Bazarov

Tom said:
Gerard said:
Presently I have some difficulties with the following type of code
which is understandably causing a segfault:

//---- begin code ----

#include <valarray>
#include <iostream>


using namespace std;


class SomeClass {

private:
valarray <double> mx;

public:
SomeClass(valarray <double>& x) {mx = x;}

The above has undefined behaviour. Once you enter the constructor, mx
has size 0, but you are assigning to it a valarray of size != 0, which
isn't allowed. [..]

Alright, it was my mistake to have forgotten about this. When I took the
code, I did the change and didn't think twice about it.

Gerard, I am sorry for having missed this particular part in your code.

V
 
V

Victor Bazarov

Victor said:
Gerard said:
Victor said:
Gerard Kramer wrote:
Presently I have some difficulties with the following type of code
which is understandably causing a segfault:
[..]

It will fail at runtime because, as I understand it, mx is a
zero-size valarray and hence mx[1] does not exist.

It *will* fail or it *does* fail?

It *will* fail (by looking at the code) and so it *does* (by
compiling and running it.)

The reason I asked was that I took your code, compiled it and ran it,
and it ran fine on VC++ 2005.

Sorry, this just shows that undefined behaviour is just that, undefined,
and compiling and running is not necessarily the proof of correctness.

I still stand by the advice to step through it in a debugger.

V
 
R

Richard Herring

I'd recommend making this take a const reference, but it shouldn't make
any difference to the rest of the code.


... and I'd recommend using an initializer list, but again it shouldn't
make any difference.

: mx(x) {}

Oops. That certainly does make a difference. Instead of checking the
standard I looked at an old document which wrongly implied that
assignment resizes.
 
G

Gerard Kramer

Gerard said:
Presently I have some difficulties with the following type of code which
is understandably causing a segfault:

//---- begin code ----

#include <valarray>
#include <iostream>


using namespace std;


class SomeClass {

private:
valarray <double> mx;

public:
SomeClass(valarray <double>& x) {mx = x;}
void func() {cout << mx[1];} // <---- Segfault here.

};


int main () {
valarray <double> x(5,10);
SomeClass foo(x);

foo.func();

return 0;
}

//---- end code ----

It will fail at runtime because, as I understand it, mx is a zero-size
valarray and hence mx[1] does not exist.

Yet (for a simple numerical code) I would like something similar to the
above to work, i.e. I'd like to pass a valarray of predefined size to
the constructor of a class to initialize a class-member valarray, say
mx, and after reference to mx's elements as mx[0], mx[1] etc. As a C++
starter I'm confused about the best way to work around the problem in
the code above. Any advice would be welcome.

Regards,
Gerard.

Thank you all very much for your replies. (Including Victor's ;-) I
understand the solution involving an initializer list. For some reason
my C++ notes didn't mention this "construction" but strangle claimed
that assignment should do the job.

I also took note of Tom Widmer's remark. Probably you're right about
Blitz and others outperforming the valarray template class. Actually, I
did install Blitz on my machine, but only some time after encountering
valarray, which kept me wondering how to make my original code work.

Regards,
Gerard.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top