Re: Usage of ? : expressions
Den 28.01.11 01.24, skrev red floyd:
Can you post a minimal compilable, executable example that exhibits
the behavior in question?
Sure. I made an example program that implements my array class, you find
it below. It compiles with
g++ -DUSE_FFTW -L/opt/local/lib -I/opt/local/include -o array_class
array_class.cpp -lfftw3 -lm
It links against fftw3, remove line 2 from the code and omit -DUSE_FFTW
-lfftw -lm from the compile line to not use fftw3.
The purpose of this class is to allocate an array of size either
(Nx+2)*(My+2) if has_gp=true or Nx*My if has_gp=false.
It should properly allocate memory and the () operator is to be used to
access individual elements. Also the =, + and += operator should work
properly. But I think my code below is just fine :)
I removed the underscore and use size_t as the type for sizes now.
Before, I often used the underscore for private members of classes.
The code works fine on its own. When using this class in my
bigger project though, I got sporadic errors in the malloc_zone_malloc,
that I traced back to the operator+ from this class. They caused the
whole program to crash.
So my theory that it was the (? :) expressions that were causing
exceptions in malloc_zone_malloc is wrong. I will keep looking
through my project then. Thank you all for clarifying the use of
the ?: operator.
Cheers, Ralph
#include<iostream>
#include <fftw3.h>
using namespace std;
class slab_array{
public:
/// Create Nx * My array, with possible ghost points and initialize to
real value.
slab_array(int, int, bool, double);
~slab_array();
///Access functions for single array elements.
double& operator() (int, int);
double operator() (int, int) const;
///Assignment to double
slab_array& operator= (const double&);
slab_array& operator+= (const double&);
///Assignment operator
slab_array& operator= (const slab_array&);
/// Elementwise addition
slab_array& operator+=(const slab_array& rhs);
const slab_array operator+(const slab_array& other) const;
/// Returns a pointer to array.
double* get_array() const;
bool has_ghost_points() const;
void dump_array();
private:
double* array;
size_t Nx;
size_t My;
bool has_gp;
};
slab_array :: slab_array(int nx, int my, bool with_gp, double init) :
array(NULL),
Nx(nx),
My(my),
has_gp(with_gp)
{
#ifdef USE_FFTW
array = (double*) fftw_malloc( sizeof(double) * (has_gp ?
(Nx+2)*(My+2) : (Nx*My) ) );
#endif
#ifndef USE_FFTW
array = new double[ (has_gp ? (Nx+2)*(My+2) : (Nx*My) ) ];
#endif
// Notice the ? : structure in the loop header
for ( size_t n = 0; n < (has_gp ? Nx+2 : Nx); n++ ) {
for ( size_t m = 0; m < (has_gp ? My+2 : My) ; m++ ) {
array[m + n * (has_gp ? My+2 : My)] = init;
} // for
} // for
}
slab_array :: ~slab_array() {
#ifdef USE_FFTW
fftw_free(array);
#endif
#ifndef USE_FFTW
delete array;
#endif
array = NULL;
}
/// Access elements
double& slab_array::operator() (int n, int m){
if ( n > static_cast<int> (has_gp ? Nx+2 : Nx) ){
cerr << "Out of bounds: " << n << "> " << (has_gp ? Nx+2 : Nx) <<"\n";
return array[0];
}
if ( m > static_cast<int>(has_gp ? My+2 : My) ){
cerr << "Out of bounds: " << m << "> "<< (has_gp ? My+2 : My) <<"\n";
return array[0];
}
return ( array[ m + n * (has_gp ? My+2 : My) ] );
}
double slab_array::operator() (int n, int m) const{
if ( n > static_cast<int> (has_gp ? Nx+2 : Nx) )
return -2.0;
if ( m > static_cast<int> (has_gp ? My+2 : My) )
return -2.0;
return ( array[ m + n * (has_gp ? My+2 : My) ] );
}
/// Assign double value to all elements
slab_array& slab_array::operator= (const double& val) {
for ( unsigned int n = 0; n < Nx; n++) {
for ( unsigned int m = 0; m < My; m++) {
(*this)(n,m) = val;
}
}
return *this;
}
///Assign one slab_array to another
slab_array& slab_array::operator= (const slab_array& rhs) {
// 4 possibilities:
// 1.) rhs uses gp, dst uses no gp => bad, do not copy ghostpoints
// 2.) rhs uses gp, dst uses gp => ok, copy ghostpoints
// 3.) rhs uses no gp, dst uses no gp => ok, do not copy ghostpoints
// 4.) rhs uses no gp, dst uses gp => bad, do not copy ghostpoints
if ( this != &rhs ) {
unsigned int n_up = static_cast<int> (Nx);
unsigned int m_up = static_cast<int> (My);
if ( rhs.has_ghost_points() == true && (*this).has_ghost_points() ==
true ) {
n_up = static_cast<int>(Nx+2);
m_up = static_cast<int>(My+2);
}
for ( unsigned int n = 0; n < n_up; n++) {
for ( unsigned int m = 0; m < m_up; m++ ) {
(*this)(n,m) = rhs(n,m);
}
}
}
return *this;
}
/// Elementwise addition with another slab array
slab_array& slab_array::operator+=(const slab_array& rhs) {
unsigned int n_up = static_cast<int>(Nx);
unsigned int m_up = static_cast<int>(My);
if ( rhs.has_ghost_points() == true && (*this).has_ghost_points() ==
true ) {
n_up = static_cast<int>(Nx+2);
m_up = static_cast<int>(My+2);
}
for ( unsigned int n = 0; n < n_up; n++ ) {
for ( unsigned int m = 0; m < m_up; m++ ) {
(*this)(n,m) += rhs(n,m);
}
}
return *this;
}
const slab_array slab_array::operator+(const slab_array& other ) const {
slab_array result(*this);
result += other;
return result;
}
void slab_array::dump_array(){
for ( int n = 0; n < static_cast<int>(has_gp ? Nx+2 : Nx); n++) {
for ( int m = 0; m < static_cast<int>(has_gp ? My+2 : My); m++) {
cout << array[m + n * static_cast<int>(has_gp? Nx+2 : Nx)] << "\t";
}
cout << "\n";
}
}
double* slab_array::get_array() const{
return array;
}
bool slab_array::has_ghost_points() const{
return(has_gp);
}
int main(void){
const size_t Nx = 8;
const size_t My = 8;
slab_array a1(Nx, My, false, 3.0);
slab_array a2(Nx, My, true, 5.0);
cout << "a1 = \n";
a1.dump_array();
cout << "a2 = \n";
a2.dump_array();
cout << "a1+a2 = \n";
a1 += a2;
a1.dump_array();
return(0);
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]