From f19bff8ddbbb0fa2df4dc689754e97d9dceadf6c Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 2 Feb 2023 16:41:05 -0700 Subject: [PATCH 01/16] Per #2402, updating the sonarqube properties to track progress for this bugfix branch. DO NOT include these changes in the pull request for main_v11.0. --- internal/scripts/sonarqube/sonar-project.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/scripts/sonarqube/sonar-project.properties b/internal/scripts/sonarqube/sonar-project.properties index a18d10de16..95b06aa02d 100644 --- a/internal/scripts/sonarqube/sonar-project.properties +++ b/internal/scripts/sonarqube/sonar-project.properties @@ -1,5 +1,5 @@ -sonar.projectKey=org.sonarqube:MET_develop_NB -sonar.projectName=MET Nightly Build +sonar.projectKey=org.sonarqube:bugfix_2402_main_v11.0_sonarqube +sonar.projectName=bugfix_2402_main_v11.0_sonarqube sonar.projectVersion=1.0 sonar.sources=src From 4100841f1c6e8a2966c64738e5a3ccad98a68738 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 2 Feb 2023 17:21:47 -0700 Subject: [PATCH 02/16] Per #2402, revert the sonar properties back to what they were. When I run manually for this bugfix branch on seneca I'm just using a local copy with changes rather than this version that lives in the repo. --- internal/scripts/sonarqube/sonar-project.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/scripts/sonarqube/sonar-project.properties b/internal/scripts/sonarqube/sonar-project.properties index 95b06aa02d..a18d10de16 100644 --- a/internal/scripts/sonarqube/sonar-project.properties +++ b/internal/scripts/sonarqube/sonar-project.properties @@ -1,5 +1,5 @@ -sonar.projectKey=org.sonarqube:bugfix_2402_main_v11.0_sonarqube -sonar.projectName=bugfix_2402_main_v11.0_sonarqube +sonar.projectKey=org.sonarqube:MET_develop_NB +sonar.projectName=MET Nightly Build sonar.projectVersion=1.0 sonar.sources=src From f882d976262dab7a1c65789329aa1f5d4d6fc869 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 15 Feb 2023 14:33:45 -0700 Subject: [PATCH 03/16] Per #2402, reimplement the PiecewiseLinear class using std::vector to hopefully avoid SonarQube findings. --- src/basic/vx_math/pwl.cc | 311 ++++++++------------------------------- src/basic/vx_math/pwl.h | 21 +-- 2 files changed, 63 insertions(+), 269 deletions(-) diff --git a/src/basic/vx_math/pwl.cc b/src/basic/vx_math/pwl.cc index eef083a600..411a1f734b 100644 --- a/src/basic/vx_math/pwl.cc +++ b/src/basic/vx_math/pwl.cc @@ -57,12 +57,7 @@ PiecewiseLinear::~PiecewiseLinear() { -n_alloc = N = 0; - -if ( X ) { delete [] X; X = (double *) 0; } -if ( Y ) { delete [] Y; Y = (double *) 0; } - - if ( Name != "" ) { Name.clear(); } +clear(); } @@ -100,34 +95,32 @@ return ( *this ); //////////////////////////////////////////////////////////////////////// -void PiecewiseLinear::init_from_scratch() +PiecewiseLinear::PiecewiseLinear(const char *NAME, int Npoints, const double *XX, const double *YY) { -n_alloc = N = 0; +init_from_scratch(); -Name.clear(); +Name = NAME; -X = Y = (double *) 0; +for (int j=0; j memory allocation error\n\n"; - exit ( 1 ); +out << prefix << "PiecewiseLinear ... \n"; -} +out << prefix << " Name = " << Name << "\n"; -memset(u, 0, n*sizeof(double)); -memset(v, 0, n*sizeof(double)); +out << prefix << " # Points = " << N << "\n"; - // - // copy any existing information over - // -for (k=0; k 0 ) { + out.width(10); out.precision(3); out << (Y[j]); - delete [] X; X = (double *) 0; - delete [] Y; Y = (double *) 0; + out << "\n"; } - // - // swap - // - -X = u; u = (double *) 0; -Y = v; v = (double *) 0; - - // - // done - // - -n_alloc = n; +out.flush(); return; @@ -253,26 +208,13 @@ return; //////////////////////////////////////////////////////////////////////// -PiecewiseLinear::PiecewiseLinear(const char *NAME, int Npoints, const double *XX, const double *YY) +void PiecewiseLinear::set_name(const ConcatString NAME) { -init_from_scratch(); - - if ( NAME ) set_name((string)NAME); - -extend(Npoints); +Name = NAME; -int j; - -for (j=0; j= N) ) { +if ( k < 0 || k >= X.size() ) { mlog << Error << "\nPiecewiseLinear::x(int) -> range check error\n\n"; @@ -304,7 +246,7 @@ double PiecewiseLinear::y(int k) const { -if ( (k < 0) || (k >= N) ) { +if ( k < 0 || k >= Y.size() ) { mlog << Error << "\nPiecewiseLinear::y(int) -> range check error\n\n"; @@ -320,10 +262,27 @@ return ( Y[k] ); //////////////////////////////////////////////////////////////////////// +void PiecewiseLinear::add_point(double xx, double yy) + +{ + +X.push_back(xx); +Y.push_back(yy); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + double PiecewiseLinear::operator()(double t) const { +int N = X.size(); + if ( t < X[0] ) return ( Y[0] ); if ( t > X[N - 1] ) return ( Y[N - 1] ); @@ -340,7 +299,6 @@ for (j=0; j<(N - 1); ++j) { } - // // flow of control should not reach this point // @@ -355,87 +313,6 @@ return ( -100 ); // just to satisfy the compiler } -//////////////////////////////////////////////////////////////////////// - - -void PiecewiseLinear::set_name(const ConcatString T) - -{ - - if ( Name != "" ) { Name.clear(); } - - - Name = T; - - - return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -void PiecewiseLinear::add_point(double xx, double yy) - -{ - -extend(N + 1); - -X[N] = xx; -Y[N] = yy; - -++N; - - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -void PiecewiseLinear::dump(ostream & out, int indent_depth) const - -{ - -int j; -Indent prefix; - - -prefix.depth = indent_depth; - - -out << prefix << "PiecewiseLinear ... \n"; - -out << prefix << " Name = " << Name << "\n"; - -out << prefix << " # Points = " << N << "\n"; - - -out.setf(ios::fixed); - -for (j=0; j= 0) && (x[j] > x_in) ) --j; - - // - // range check - // - -if ( j < 0 ) { y_out = y[0]; return ( 0 ); } - -if ( j >= (n - 1) ) { y_out = y[n - 1]; return ( 0 ); } - - // - // interpolate - // - -if ( is_eq(x[j + 1], x[j]) ) { - - y_out = y[j]; - -} else { - - m = (y[j + 1] - y[j])/(x[j + 1] - x[j]); - - y_out = y[j] + m*(x_in - x[j]); - -} - - // - // done - // - -return ( 1 ); - -} - - -//////////////////////////////////////////////////////////////////////// - - - diff --git a/src/basic/vx_math/pwl.h b/src/basic/vx_math/pwl.h index 410fe66993..eb4d64dfea 100644 --- a/src/basic/vx_math/pwl.h +++ b/src/basic/vx_math/pwl.h @@ -18,7 +18,7 @@ #include - +#include //////////////////////////////////////////////////////////////////////// @@ -39,17 +39,10 @@ class PiecewiseLinear { protected: - void extend(int); - - int N; - - int n_alloc; - ConcatString Name; - double * X; - double * Y; - + std::vector X; + std::vector Y; public: @@ -95,7 +88,7 @@ class PiecewiseLinear { //////////////////////////////////////////////////////////////////////// -inline int PiecewiseLinear::n_points() const { return ( N ); } +inline int PiecewiseLinear::n_points() const { return ( X.size() ); } inline const char * PiecewiseLinear::name() const { return ( Name.c_str() ); } @@ -103,12 +96,6 @@ inline const char * PiecewiseLinear::name() const { return ( Name.c_str() ); } //////////////////////////////////////////////////////////////////////// -extern int pwl_interpolate(const double * y, const double * x, int n, double x_in, double & y_out); - - -//////////////////////////////////////////////////////////////////////// - - #endif /* __PIECEWISE_LINEAR_H__ */ From 4e365034909b14310219641a06cf2112746249cb Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 16 Feb 2023 08:44:30 -0700 Subject: [PATCH 04/16] Per #2402, updates ascii_table.cc by replacing dynamically allocated memory with std::vector to avoid SonarQube findings about out of bounds memory access. --- src/basic/vx_util/ascii_table.cc | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/basic/vx_util/ascii_table.cc b/src/basic/vx_util/ascii_table.cc index 343a5aad23..988b4bdc8f 100644 --- a/src/basic/vx_util/ascii_table.cc +++ b/src/basic/vx_util/ascii_table.cc @@ -19,6 +19,7 @@ using namespace std; #include #include #include +#include #include "vx_log.h" #include "vx_cal.h" @@ -1336,21 +1337,14 @@ if ( Nrows < 0 || Nrows >= INT_MAX ) { if ( Nrows <= 2 ) return; -int * left = new int [Nrows]; -int * right = new int [Nrows]; +std::vector left (Nrows, 0); +std::vector right(Nrows, 0); int r, c, n, k; int max_left, max_right; const char fill_char = ' '; const int r_start = 1; // skip the header row - -for (r=0; r Date: Thu, 16 Feb 2023 11:33:59 -0700 Subject: [PATCH 05/16] Per #2402, update the CRC_Array template class to use stl vectors instead of dyanmically allocating memory to avoid SonarQube findings. --- src/basic/vx_util/crc_array.h | 75 +++++------------------------------ 1 file changed, 11 insertions(+), 64 deletions(-) diff --git a/src/basic/vx_util/crc_array.h b/src/basic/vx_util/crc_array.h index 2b7dcb52e3..8b34673c62 100644 --- a/src/basic/vx_util/crc_array.h +++ b/src/basic/vx_util/crc_array.h @@ -19,6 +19,7 @@ #include +#include #include "num_array.h" #include "int_array.h" @@ -34,27 +35,6 @@ static const int crc_array_alloc_inc = 25; -//////////////////////////////////////////////////////////////////////// - - -template - -int is_bigger(const void * p1, const void * p2) - -{ - -const T & a = *((T *) p1); -const T & b = *((T *) p2); - -if ( a < b ) return ( -1 ); -if ( a > b ) return ( 1 ); - -return ( 0 ); - -} - - - //////////////////////////////////////////////////////////////////////// @@ -69,7 +49,7 @@ class CRC_Array { void assign(const CRC_Array &); - T * e; + std::vector e; int Nelements; @@ -144,12 +124,6 @@ class CRC_Array { }; -//////////////////////////////////////////////////////////////////////// - - -// static int is_bigger(const void *, const void *); - - //////////////////////////////////////////////////////////////////////// @@ -205,8 +179,6 @@ void CRC_Array::init_from_scratch() { -e = (T *) 0; - clear(); return; @@ -223,7 +195,7 @@ void CRC_Array::clear() { -if ( e ) { delete [] e; e = (T *) 0; } +e.clear(); Nelements = Nalloc = 0; @@ -286,36 +258,7 @@ if ( ! exact ) { } -T * u = (T *) 0; - -u = new T [len]; - -if ( !u ) { - - mlog << Error << "\nvoid CRC_Array::extend(int, bool) -> " - << "memory allocation error\n\n"; - - exit ( 1 ); - -} - -int j; - -memset(u, 0, len*sizeof(T)); - -if ( e ) { - - for (j=0; j::add(const T & k) extend(Nelements + 1, false); -e[Nelements++] = k; +e.push_back(k); + +Nelements++; return; @@ -555,7 +500,9 @@ int j; for (j=0; j<(a.Nelements); ++j) { - e[Nelements++] = a.e[j]; + e.push_back(a.e[j]); + + Nelements++; } @@ -604,7 +551,7 @@ void CRC_Array::sort_increasing() if ( Nelements <= 1 ) return; -qsort(e, Nelements, sizeof(*e), is_bigger); +std::sort(e.begin(), e.end()); return; From 35c186d32fbeb1f4e75e1af9c6dc6fa6272a9400 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 16 Feb 2023 11:51:00 -0700 Subject: [PATCH 06/16] Per #2402, reimplement the TableFlatFile class using std::vector instead of dynamically allocating memory to eliminate SonarQube findings. --- src/libcode/vx_data2d/table_lookup.cc | 253 +++++++++----------------- src/libcode/vx_data2d/table_lookup.h | 6 +- 2 files changed, 88 insertions(+), 171 deletions(-) diff --git a/src/libcode/vx_data2d/table_lookup.cc b/src/libcode/vx_data2d/table_lookup.cc index dbc920ae21..d9c4605d9e 100644 --- a/src/libcode/vx_data2d/table_lookup.cc +++ b/src/libcode/vx_data2d/table_lookup.cc @@ -617,9 +617,6 @@ void TableFlatFile::init_from_scratch() { -g1e = (Grib1TableEntry **) 0; -g2e = (Grib2TableEntry **) 0; - clear(); } @@ -634,30 +631,8 @@ void TableFlatFile::clear() int j; -if ( g1e ) { - - for (j=0; jdump(out, depth + 1); + g1e[j].dump(out, depth + 1); } @@ -696,7 +671,7 @@ for (j=0; jdump(out, depth + 1); + g2e[j].dump(out, depth + 1); } @@ -722,15 +697,7 @@ if ( f.N_grib1_elements != 0 ) { N_grib1_elements = N_grib1_alloc = f.N_grib1_elements; - g1e = new Grib1TableEntry * [N_grib1_elements]; - - for (j=0; j 0 ) { - - for (j=0; j 0 ) { - - for (j=0; jparse_line(line.c_str()); + status = e.parse_line(line.c_str()); if ( ! status ) { @@ -957,9 +873,11 @@ while ( line.read_line(in) ) { } // - // increment counter + // store entry and increment counter // + g1e.push_back(e); + j++; } // while @@ -988,6 +906,7 @@ bool TableFlatFile::read_grib2(istream & in, const char * filename, const int n) int j; ConcatString line; +Grib2TableEntry e; bool status = false; // @@ -1016,9 +935,7 @@ while ( line.read_line(in) ) { line << "\n"; - g2e[N_grib2_elements + j] = new Grib2TableEntry; - - status = g2e[N_grib2_elements + j]->parse_line(line.c_str()); + status = e.parse_line(line.c_str()); if ( ! status ) { @@ -1031,9 +948,11 @@ while ( line.read_line(in) ) { } // - // increment counter + // store entry and increment counter // + g2e.push_back(e); + j++; } // while @@ -1062,9 +981,9 @@ e.clear(); for (j=0; jcode == code) && (g1e[j]->table_number == table_number) ) { + if ( (g1e[j].code == code) && (g1e[j].table_number == table_number) ) { - e = *(g1e[j]); + e = g1e[j]; return ( true ); @@ -1091,14 +1010,14 @@ bool TableFlatFile::lookup_grib1(int code, int table_number, int center, int sub for (j=0; jsubcenter == -1){ + if( g1e[j].subcenter == -1){ matching_subsenter = -1; } - if ( (g1e[j]->code == code) && (g1e[j]->table_number == table_number) - && (g1e[j]->center == center) && (g1e[j]->subcenter == matching_subsenter)) { + if ( (g1e[j].code == code) && (g1e[j].table_number == table_number) && + (g1e[j].center == center) && (g1e[j].subcenter == matching_subsenter)) { - e = *(g1e[j]); + e = g1e[j]; return ( true ); @@ -1138,15 +1057,15 @@ bool TableFlatFile::lookup_grib1(const char * parm_name, int table_number, int c n_matches = 0; // build a list of matches - vector matches; + vector matches; for(int j=0; j < N_grib1_elements; j++){ - if( g1e[j]->parm_name != parm_name || - (bad_data_int != table_number && g1e[j]->table_number != table_number) || - (bad_data_int != code && g1e[j]->code != code ) ) + if( g1e[j].parm_name != parm_name || + (bad_data_int != table_number && g1e[j].table_number != table_number) || + (bad_data_int != code && g1e[j].code != code) ) continue; - if( n_matches++ == 0 ) e = *(g1e[j]); + if( n_matches++ == 0 ) e = g1e[j]; matches.push_back( g1e[j] ); } @@ -1162,11 +1081,11 @@ bool TableFlatFile::lookup_grib1(const char * parm_name, int table_number, int c msg << "):\n"; mlog << Debug(3) << "\n" << msg; - for(vector::iterator it = matches.begin(); + for(vector::iterator it = matches.begin(); it < matches.end(); it++) - mlog << Debug(3) << " parm_name: " << (*it)->parm_name - << ", table_number = " << (*it)->table_number - << ", code = " << (*it)->code << "\n"; + mlog << Debug(3) << " parm_name: " << (it)->parm_name + << ", table_number = " << (it)->table_number + << ", code = " << (it)->code << "\n"; mlog << Debug(3) << "Using the first match found: " << " parm_name: " << e.parm_name @@ -1193,22 +1112,22 @@ bool TableFlatFile::lookup_grib1(const char * parm_name, int table_number, int c n_matches = 0; // build a list of matches - vector matches; + vector matches; int matching_subsenter; for(int j=0; j < N_grib1_elements; j++){ matching_subsenter = subcenter; - if( g1e[j]->subcenter == -1){ + if( g1e[j].subcenter == -1){ matching_subsenter = -1; } - if( g1e[j]->parm_name != parm_name || - (bad_data_int != table_number && g1e[j]->table_number != table_number) || - (bad_data_int != code && g1e[j]->code != code ) || - (bad_data_int != center && g1e[j]->center != center ) || - (bad_data_int != matching_subsenter && g1e[j]->subcenter != matching_subsenter) ) + if( g1e[j].parm_name != parm_name || + (bad_data_int != table_number && g1e[j].table_number != table_number) || + (bad_data_int != code && g1e[j].code != code) || + (bad_data_int != center && g1e[j].center != center) || + (bad_data_int != matching_subsenter && g1e[j].subcenter != matching_subsenter) ) continue; - if( n_matches++ == 0 ) e = *(g1e[j]); + if( n_matches++ == 0 ) e = g1e[j]; matches.push_back( g1e[j] ); } @@ -1224,14 +1143,14 @@ bool TableFlatFile::lookup_grib1(const char * parm_name, int table_number, int c msg << "):\n"; mlog << Debug(3) << "\n" << msg; - for(vector::iterator it = matches.begin(); + for(vector::iterator it = matches.begin(); it < matches.end(); it++) { - mlog << Debug(3) << " parm_name: " << (*it)->parm_name - << ", table_number = " << (*it)->table_number - << ", code = " << (*it)->code - << ", center = " << (*it)->center - << ", subcenter = " << (*it)->subcenter << "\n"; + mlog << Debug(3) << " parm_name: " << (it)->parm_name + << ", table_number = " << (it)->table_number + << ", code = " << (it)->code + << ", center = " << (it)->center + << ", subcenter = " << (it)->subcenter << "\n"; } mlog << Debug(3) << "Using the first match found: " @@ -1272,9 +1191,9 @@ e.clear(); for (j=0; jindex_a == a) && (g2e[j]->index_b == b) && (g2e[j]->index_c == c) ) { + if ( (g2e[j].index_a == a) && (g2e[j].index_b == b) && (g2e[j].index_c == c) ) { - e = *(g2e[j]); + e = g2e[j]; return ( true ); @@ -1302,17 +1221,17 @@ bool TableFlatFile::lookup_grib2(int a, int b, int c, for (j=0; jindex_a != a || - g2e[j]->index_b != b || - g2e[j]->index_c != c ) continue; + if ( g2e[j].index_a != a || + g2e[j].index_b != b || + g2e[j].index_c != c ) continue; // Check master table, center, and local table - if ( (bad_data_int != mtab && g2e[j]->mtab_low > mtab) || - (bad_data_int != mtab && g2e[j]->mtab_high < mtab) || - (bad_data_int != cntr && g2e[j]->cntr > 0 && g2e[j]->cntr != cntr) || - (bad_data_int != ltab && g2e[j]->ltab > 0 && g2e[j]->ltab != ltab) ) continue; + if ( (bad_data_int != mtab && g2e[j].mtab_low > mtab) || + (bad_data_int != mtab && g2e[j].mtab_high < mtab) || + (bad_data_int != cntr && g2e[j].cntr > 0 && g2e[j].cntr != cntr) || + (bad_data_int != ltab && g2e[j].ltab > 0 && g2e[j].ltab != ltab) ) continue; - e = *(g2e[j]); + e = g2e[j]; return ( true ); @@ -1335,16 +1254,16 @@ bool TableFlatFile::lookup_grib2(const char * parm_name, int a, int b, int c, n_matches = 0; // build a list of matches - vector matches; + vector matches; for(int j=0; jparm_name != parm_name || - (bad_data_int != a && g2e[j]->index_a != a) || - (bad_data_int != b && g2e[j]->index_b != b) || - (bad_data_int != c && g2e[j]->index_c != c) ) + if( g2e[j].parm_name != parm_name || + (bad_data_int != a && g2e[j].index_a != a) || + (bad_data_int != b && g2e[j].index_b != b) || + (bad_data_int != c && g2e[j].index_c != c) ) continue; - if( n_matches++ == 0 ) e = *(g2e[j]); + if( n_matches++ == 0 ) e = g2e[j]; matches.push_back( g2e[j] ); } @@ -1361,12 +1280,12 @@ bool TableFlatFile::lookup_grib2(const char * parm_name, int a, int b, int c, msg << "):\n"; mlog << Debug(3) << "\n" << msg; - for(vector::iterator it = matches.begin(); + for(vector::iterator it = matches.begin(); it < matches.end(); it++) - mlog << Debug(3) << " parm_name: " << (*it)->parm_name - << ", index_a = " << (*it)->index_a - << ", index_b = " << (*it)->index_b - << ", index_c = " << (*it)->index_c << "\n"; + mlog << Debug(3) << " parm_name: " << (it)->parm_name + << ", index_a = " << (it)->index_a + << ", index_b = " << (it)->index_b + << ", index_c = " << (it)->index_c << "\n"; mlog << Debug(3) << "Using the first match found: " << " parm_name: " << e.parm_name @@ -1395,20 +1314,20 @@ bool TableFlatFile::lookup_grib2(const char * parm_name, n_matches = 0; // build a list of matches - vector matches; + vector matches; for(int j=0; jparm_name != parm_name || - (bad_data_int != a && g2e[j]->index_a != a) || - (bad_data_int != b && g2e[j]->index_b != b) || - (bad_data_int != c && g2e[j]->index_c != c) || - (bad_data_int != mtab && g2e[j]->mtab_low > mtab) || - (bad_data_int != mtab && g2e[j]->mtab_high < mtab) || - (bad_data_int != cntr && g2e[j]->cntr > 0 && g2e[j]->cntr != cntr) || - (bad_data_int != ltab && g2e[j]->ltab > 0 && g2e[j]->ltab != ltab) ) + if( g2e[j].parm_name != parm_name || + (bad_data_int != a && g2e[j].index_a != a) || + (bad_data_int != b && g2e[j].index_b != b) || + (bad_data_int != c && g2e[j].index_c != c) || + (bad_data_int != mtab && g2e[j].mtab_low > mtab) || + (bad_data_int != mtab && g2e[j].mtab_high < mtab) || + (bad_data_int != cntr && g2e[j].cntr > 0 && g2e[j].cntr != cntr) || + (bad_data_int != ltab && g2e[j].ltab > 0 && g2e[j].ltab != ltab) ) continue; - if( n_matches++ == 0 ) e = *(g2e[j]); + if( n_matches++ == 0 ) e = g2e[j]; matches.push_back( g2e[j] ); } @@ -1428,15 +1347,15 @@ bool TableFlatFile::lookup_grib2(const char * parm_name, msg << "):\n"; mlog << Debug(3) << "\n" << msg; - for(vector::iterator it = matches.begin(); + for(vector::iterator it = matches.begin(); it < matches.end(); it++) - mlog << Debug(3) << " parm_name: " << (*it)->parm_name - << ", index_a = " << (*it)->index_a - << ", grib2_mtab = " << (*it)->mtab_set - << ", grib2_cntr = " << (*it)->cntr - << ", grib2_ltab = " << (*it)->ltab - << ", index_b = " << (*it)->index_b - << ", index_c = " << (*it)->index_c + mlog << Debug(3) << " parm_name: " << (it)->parm_name + << ", index_a = " << (it)->index_a + << ", grib2_mtab = " << (it)->mtab_set + << ", grib2_cntr = " << (it)->cntr + << ", grib2_ltab = " << (it)->ltab + << ", index_b = " << (it)->index_b + << ", index_c = " << (it)->index_c << "\n"; mlog << Debug(3) << "Using the first match found: " diff --git a/src/libcode/vx_data2d/table_lookup.h b/src/libcode/vx_data2d/table_lookup.h index a234bf72bb..e376293a4e 100644 --- a/src/libcode/vx_data2d/table_lookup.h +++ b/src/libcode/vx_data2d/table_lookup.h @@ -145,8 +145,8 @@ class TableFlatFile { void extend_grib1(int); void extend_grib2(int); - Grib1TableEntry ** g1e; // elements ... allocated - Grib2TableEntry ** g2e; // elements ... allocated + std::vector g1e; + std::vector g2e; int N_grib1_elements; int N_grib2_elements; @@ -229,5 +229,3 @@ extern TableFlatFile GribTable; //////////////////////////////////////////////////////////////////////// - - From f1e61fee77daf4e6dc5c679ca6a279d435225c70 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 16 Feb 2023 12:00:43 -0700 Subject: [PATCH 07/16] Per #2402, define and use a new SemiLatLonData::clear() to avoid a SonarQube finding. --- src/libcode/vx_grid/grid_base.cc | 17 +++++++++++++++++ src/libcode/vx_grid/semilatlon_grid.cc | 2 +- src/libcode/vx_grid/semilatlon_grid_defs.h | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/libcode/vx_grid/grid_base.cc b/src/libcode/vx_grid/grid_base.cc index b909547805..88b2f85383 100644 --- a/src/libcode/vx_grid/grid_base.cc +++ b/src/libcode/vx_grid/grid_base.cc @@ -239,6 +239,23 @@ mlog << Debug(grid_debug_level) } +//////////////////////////////////////////////////////////////////////// + + +void SemiLatLonData::clear() + +{ + +name = (const char *) 0; + +lats.clear(); +lons.clear(); +levels.clear(); +times.clear(); + +} + + //////////////////////////////////////////////////////////////////////// diff --git a/src/libcode/vx_grid/semilatlon_grid.cc b/src/libcode/vx_grid/semilatlon_grid.cc index 9018bc400e..76096ffb32 100644 --- a/src/libcode/vx_grid/semilatlon_grid.cc +++ b/src/libcode/vx_grid/semilatlon_grid.cc @@ -173,7 +173,7 @@ IsLatLon = false; Nx = 0; Ny = 0; -memset(&Data, 0, sizeof(Data)); +Data.clear(); return; diff --git a/src/libcode/vx_grid/semilatlon_grid_defs.h b/src/libcode/vx_grid/semilatlon_grid_defs.h index 5511007469..25529c66f0 100644 --- a/src/libcode/vx_grid/semilatlon_grid_defs.h +++ b/src/libcode/vx_grid/semilatlon_grid_defs.h @@ -29,6 +29,7 @@ struct SemiLatLonData { NumArray times; void dump(); + void clear(); }; From 4b257eac058d6463901f65d41a3d4ba5590ca4a2 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 16 Feb 2023 12:21:16 -0700 Subject: [PATCH 08/16] Per #2402, reimplement FcstObsSet using std::vector instead of dynamically allocated memory to get rid of SonarQube findings. --- src/libcode/vx_shapedata/set.cc | 78 ++++++++++----------------------- src/libcode/vx_shapedata/set.h | 16 ++++--- 2 files changed, 32 insertions(+), 62 deletions(-) diff --git a/src/libcode/vx_shapedata/set.cc b/src/libcode/vx_shapedata/set.cc index 882aa29bd0..6bc246503f 100644 --- a/src/libcode/vx_shapedata/set.cc +++ b/src/libcode/vx_shapedata/set.cc @@ -94,10 +94,6 @@ void FcstObsSet::init_from_scratch() { -fcst_number = 0; - - obs_number = 0; - all_clear(); extend_fcst (50); @@ -115,9 +111,6 @@ void FcstObsSet::clear() { -// if ( fcst_number ) { delete [] fcst_number; fcst_number = 0; } -// if ( obs_number ) { delete [] obs_number; obs_number = 0; } - int j; for (j=0; j 0 ) { extend_fcst (s.n_fcst_alloc); - memcpy(fcst_number, s.fcst_number, (s.n_fcst_alloc)*sizeof(int)); + fcst_number = s.fcst_number; } @@ -174,7 +165,7 @@ if ( s.n_obs_alloc > 0 ) { extend_obs (s.n_obs_alloc); - memcpy(obs_number, s.obs_number, (s.n_obs_alloc)*sizeof(int)); + obs_number = s.obs_number; } @@ -220,30 +211,19 @@ return; /////////////////////////////////////////////////////////////////////////////// -void FcstObsSet::extend(int * & a, int & n_alloc, const int N) +void FcstObsSet::extend(std::vector & a, int & n_alloc, const int N) { if ( N <= n_alloc ) return; -int j, k; -int * u = 0; - -k = N/fcst_obs_set_alloc_inc; +int k = N/fcst_obs_set_alloc_inc; if ( N%fcst_obs_set_alloc_inc ) ++k; k *= fcst_obs_set_alloc_inc; -u = new int [k]; - -if ( a ) memcpy(u, a, n_alloc*sizeof(int)); - -for (j=n_alloc; j + + +/////////////////////////////////////////////////////////////////////////////// + + static const int fcst_obs_set_alloc_inc = 50; @@ -40,7 +46,7 @@ class FcstObsSet { void assign(const FcstObsSet &); - void extend(int * &, int & n_alloc, const int n_new); + void extend(std::vector &, int & n_alloc, const int n_new); public: @@ -48,8 +54,8 @@ class FcstObsSet { // data // - int * fcst_number; // allocated - int * obs_number; // allocated + std::vector fcst_number; + std::vector obs_number; int n_fcst; int n_obs; @@ -96,8 +102,6 @@ extern std::ostream & operator<<(std::ostream &, const FcstObsSet &); /////////////////////////////////////////////////////////////////////////////// -// static const int max_fcst_obs_sets = 300; - static const int set_alloc_inc = 50; @@ -118,7 +122,7 @@ class SetCollection { // data // - FcstObsSet * set; // allocated + std::vector set; int n_sets; From 0f247704ea93195acaa2221fb872e024c2a2cd7f Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 16 Feb 2023 12:30:29 -0700 Subject: [PATCH 09/16] Per #2402, update contable.cc to use std::vector instead of dynamically allocated memory. --- src/libcode/vx_statistics/contable.cc | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/src/libcode/vx_statistics/contable.cc b/src/libcode/vx_statistics/contable.cc index 286f66d7ca..940c60598b 100644 --- a/src/libcode/vx_statistics/contable.cc +++ b/src/libcode/vx_statistics/contable.cc @@ -20,6 +20,7 @@ using namespace std; #include #include #include +#include #include "contable.h" @@ -255,15 +256,13 @@ out << prefix << "\n"; int n, m, k; int w, h; int r_table, c_table; -int * col_width = (int *) 0; -char * table = (char *) 0; const int hpad = 2; const int vpad = 1; const char v_sep = '|'; const char h_sep = '-'; const char corner_sep = '+'; -col_width = new int[Ncols]; +std::vector col_width(Ncols); for (c=0; c " - << "memory allocation error\n\n"; - - exit ( 1 ); - -} - -memset(table, ' ', w*h); +std::vector table(w*h, ' '); // // top, bottom @@ -453,10 +441,6 @@ for (r_table=0; r_table Date: Thu, 16 Feb 2023 12:54:37 -0700 Subject: [PATCH 10/16] Per #2402, update the implementation of CgFontCollection to use std::vector instead of dynamically allocating memory to avoid SonarQube findings. --- src/tools/other/mode_graphics/cgraph_font.cc | 119 ++++++------------- src/tools/other/mode_graphics/cgraph_font.h | 10 +- 2 files changed, 39 insertions(+), 90 deletions(-) diff --git a/src/tools/other/mode_graphics/cgraph_font.cc b/src/tools/other/mode_graphics/cgraph_font.cc index 9f12dca012..7892c943c5 100644 --- a/src/tools/other/mode_graphics/cgraph_font.cc +++ b/src/tools/other/mode_graphics/cgraph_font.cc @@ -115,7 +115,7 @@ face = 0; if ( !get_env(cg_font_env, gs_font_dir) ) { mlog << Error - << "\n\n CgFont::init_from_scratch() -> " + << "\nCgFont::init_from_scratch() -> " << "unable to get environment variable \"" << cg_font_env << "\"\n\n"; @@ -258,7 +258,8 @@ clear(); if ( (n < 0) || (n >= total_predef_fonts) ) { - mlog << Error << "\n\n CgFont::set_by_number(int) -> range check error\n\n"; + mlog << Error << "\nCgFont::set_by_number(int) -> " + << "range check error\n\n"; exit ( 1 ); @@ -274,7 +275,8 @@ full_afm_name << gs_font_dir << '/' << gs_font_dir << '/' << short_afm_name; if ( !file_exists(full_afm_name.c_str()) ) { - mlog << Error << "\n\n CgFont::set_by_number(int) -> can't find afm file \"" << full_afm_name << "\"\n\n"; + mlog << Error << "\nCgFont::set_by_number(int) -> " + << "can't find afm file \"" << full_afm_name << "\"\n\n"; exit ( 1 ); @@ -284,7 +286,8 @@ afm = new Afm; if ( !(afm->read(full_afm_name)) ) { - mlog << Error << "\n\n CgFont::set_by_number(int) -> trouble reading afm file \"" << full_afm_name << "\"\n\n"; + mlog << Error << "\nCgFont::set_by_number(int) -> " + << "trouble reading afm file \"" << full_afm_name << "\"\n\n"; exit ( 1 ); @@ -374,8 +377,6 @@ void CgFontCollection::init_from_scratch() { -e = (CgFont **) 0; - clear(); return; @@ -390,34 +391,28 @@ void CgFontCollection::clear() { -if ( e ) { - - int j, error; - - for (j=0; jface); +int j, error; - if ( error ) { +for (j=0; j trouble closing typeface \"" << e[j]->short_pfb_name << "\"\n\n"; + error = FT_Done_Face(e[j].face); - exit ( 1 ); + if ( error ) { - } + mlog << Error << "\nCgFontCollection::clear() -> " + << "trouble closing typeface \"" << e[j].short_pfb_name + << "\"\n\n"; - e[j]->face = 0; - - if ( e[j] ) { delete e[j]; e[j] = (CgFont *) 0; } + exit ( 1 ); } - delete [] e; e = (CgFont **) 0; + e[j].face = 0; } +e.clear(); + Nelements = Nalloc = 0; return; @@ -445,7 +440,7 @@ for (j=0; jdump(out, depth + 1); + e[j].dump(out, depth + 1); } @@ -470,37 +465,13 @@ void CgFontCollection::extend(int n) if ( n <= Nalloc ) return; -int j, k; -CgFont ** u = (CgFont **) 0; - - -k = n/alloc_inc; +int k = n/alloc_inc; if ( n%alloc_inc ) ++k; n = k*alloc_inc; -u = new CgFont * [n]; - -if ( !u ) { - - mlog << Error << "\n\n CgFontCollection::extend(int) -> memory allocation error\n\n"; - - exit ( 1 ); - -} - -for (j=0; jps_font_number == n ) return ( e[j] ); + if ( e[j].ps_font_number == n ) return ( & e[j] ); } @@ -641,7 +594,7 @@ return ( (CgFont *) 0 ); //////////////////////////////////////////////////////////////////////// -CgFont * CgFontCollection::lookup_by_ps_name(const char * name) const +CgFont * CgFontCollection::lookup_by_ps_name(const char * name) { @@ -649,7 +602,7 @@ int j; for (j=0; jps_name == name ) return ( e[j] ); + if ( e[j].ps_name == name ) return ( & e[j] ); } @@ -662,19 +615,20 @@ return ( (CgFont *) 0 ); //////////////////////////////////////////////////////////////////////// -CgFont * CgFontCollection::operator[](int k) const +CgFont * CgFontCollection::operator[](int k) { if ( (k < 0) || (k >= Nelements) ) { - mlog << Error << "\n\n CgFont * CgFontCollection::operator[](int) const -> range check error\n\n"; + mlog << Error << "\nCgFont * CgFontCollection::operator[](int) const -> " + << "range check error\n\n"; exit ( 1 ); } -return ( e[k] ); +return ( & e[k] ); } @@ -702,8 +656,3 @@ return ( false ); //////////////////////////////////////////////////////////////////////// - - - - - diff --git a/src/tools/other/mode_graphics/cgraph_font.h b/src/tools/other/mode_graphics/cgraph_font.h index f8e4f8b493..287a2c289f 100644 --- a/src/tools/other/mode_graphics/cgraph_font.h +++ b/src/tools/other/mode_graphics/cgraph_font.h @@ -18,6 +18,7 @@ #include +#include #include "ft2build.h" #include FT_FREETYPE_H @@ -98,7 +99,7 @@ class CgFontCollection { int Nalloc; - CgFont ** e; + std::vector e; public: @@ -117,12 +118,11 @@ class CgFontCollection { void add (const CgFont &); void add_no_repeat (const CgFont &); - CgFont * lookup_by_ps_name(const char *) const; + CgFont * lookup_by_ps_name(const char *); - CgFont * lookup_by_ps_font_number(int) const; // for builtin fonts + CgFont * lookup_by_ps_font_number(int); // for builtin fonts - - CgFont * operator[](int) const; + CgFont * operator[](int); }; From 1a5b076f6bea8e820d1b31db0299b68fa3dff7cc Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 16 Feb 2023 13:53:52 -0700 Subject: [PATCH 11/16] Per #2402, rollback changes to set.h and set.cc which seem to have caused a runtime memory error in MODE. --- src/libcode/vx_shapedata/set.cc | 78 +++++++++++++++++++++++---------- src/libcode/vx_shapedata/set.h | 16 +++---- 2 files changed, 62 insertions(+), 32 deletions(-) diff --git a/src/libcode/vx_shapedata/set.cc b/src/libcode/vx_shapedata/set.cc index 6bc246503f..882aa29bd0 100644 --- a/src/libcode/vx_shapedata/set.cc +++ b/src/libcode/vx_shapedata/set.cc @@ -94,6 +94,10 @@ void FcstObsSet::init_from_scratch() { +fcst_number = 0; + + obs_number = 0; + all_clear(); extend_fcst (50); @@ -111,6 +115,9 @@ void FcstObsSet::clear() { +// if ( fcst_number ) { delete [] fcst_number; fcst_number = 0; } +// if ( obs_number ) { delete [] obs_number; obs_number = 0; } + int j; for (j=0; j 0 ) { extend_fcst (s.n_fcst_alloc); - fcst_number = s.fcst_number; + memcpy(fcst_number, s.fcst_number, (s.n_fcst_alloc)*sizeof(int)); } @@ -165,7 +174,7 @@ if ( s.n_obs_alloc > 0 ) { extend_obs (s.n_obs_alloc); - obs_number = s.obs_number; + memcpy(obs_number, s.obs_number, (s.n_obs_alloc)*sizeof(int)); } @@ -211,19 +220,30 @@ return; /////////////////////////////////////////////////////////////////////////////// -void FcstObsSet::extend(std::vector & a, int & n_alloc, const int N) +void FcstObsSet::extend(int * & a, int & n_alloc, const int N) { if ( N <= n_alloc ) return; -int k = N/fcst_obs_set_alloc_inc; +int j, k; +int * u = 0; + +k = N/fcst_obs_set_alloc_inc; if ( N%fcst_obs_set_alloc_inc ) ++k; k *= fcst_obs_set_alloc_inc; -a.reserve(k); +u = new int [k]; + +if ( a ) memcpy(u, a, n_alloc*sizeof(int)); + +for (j=n_alloc; j - - -/////////////////////////////////////////////////////////////////////////////// - - static const int fcst_obs_set_alloc_inc = 50; @@ -46,7 +40,7 @@ class FcstObsSet { void assign(const FcstObsSet &); - void extend(std::vector &, int & n_alloc, const int n_new); + void extend(int * &, int & n_alloc, const int n_new); public: @@ -54,8 +48,8 @@ class FcstObsSet { // data // - std::vector fcst_number; - std::vector obs_number; + int * fcst_number; // allocated + int * obs_number; // allocated int n_fcst; int n_obs; @@ -102,6 +96,8 @@ extern std::ostream & operator<<(std::ostream &, const FcstObsSet &); /////////////////////////////////////////////////////////////////////////////// +// static const int max_fcst_obs_sets = 300; + static const int set_alloc_inc = 50; @@ -122,7 +118,7 @@ class SetCollection { // data // - std::vector set; + FcstObsSet * set; // allocated int n_sets; From a7fb2939ee8fc88902d8bc2819e1ab6dce5f8145 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 20 Feb 2023 09:23:57 -0700 Subject: [PATCH 12/16] Per #2402, ci-run-unit fix CgFontCollection::init_from_scratch() to initialize Nalloc to 0 to avoid segfault. --- src/tools/other/mode_graphics/cgraph_font.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/other/mode_graphics/cgraph_font.cc b/src/tools/other/mode_graphics/cgraph_font.cc index 7892c943c5..cecb4a8e9f 100644 --- a/src/tools/other/mode_graphics/cgraph_font.cc +++ b/src/tools/other/mode_graphics/cgraph_font.cc @@ -377,6 +377,8 @@ void CgFontCollection::init_from_scratch() { +Nelements = Nalloc = 0; + clear(); return; From 3088da11dada8aa2052c887af1f3222389f9c171 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 20 Feb 2023 09:59:08 -0700 Subject: [PATCH 13/16] Per #2402, correct CgFontCollection::clear() to clear based on the number of elements rather than the number of allocated elements after switching to using vectors. --- src/tools/other/mode_graphics/cgraph_font.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/other/mode_graphics/cgraph_font.cc b/src/tools/other/mode_graphics/cgraph_font.cc index cecb4a8e9f..335d081f6c 100644 --- a/src/tools/other/mode_graphics/cgraph_font.cc +++ b/src/tools/other/mode_graphics/cgraph_font.cc @@ -395,7 +395,7 @@ void CgFontCollection::clear() int j, error; -for (j=0; j Date: Mon, 20 Feb 2023 10:37:15 -0700 Subject: [PATCH 14/16] Per #2402, reimplement FcstObsSet using vectors instead of locally managed memory to avoid SonarQube issues. --- src/libcode/vx_shapedata/set.cc | 96 +++++++++++---------------------- src/libcode/vx_shapedata/set.h | 16 +++--- 2 files changed, 42 insertions(+), 70 deletions(-) diff --git a/src/libcode/vx_shapedata/set.cc b/src/libcode/vx_shapedata/set.cc index 882aa29bd0..ec1c6fbabb 100644 --- a/src/libcode/vx_shapedata/set.cc +++ b/src/libcode/vx_shapedata/set.cc @@ -94,9 +94,7 @@ void FcstObsSet::init_from_scratch() { -fcst_number = 0; - - obs_number = 0; +n_fcst = n_obs = 0; all_clear(); @@ -115,18 +113,13 @@ void FcstObsSet::clear() { -// if ( fcst_number ) { delete [] fcst_number; fcst_number = 0; } -// if ( obs_number ) { delete [] obs_number; obs_number = 0; } - int j; -for (j=0; j 0 ) { +if ( s.n_fcst > 0 ) { extend_fcst (s.n_fcst_alloc); - memcpy(fcst_number, s.fcst_number, (s.n_fcst_alloc)*sizeof(int)); + fcst_number = s.fcst_number; } -if ( s.n_obs_alloc > 0 ) { +if ( s.n_obs > 0 ) { extend_obs (s.n_obs_alloc); - memcpy(obs_number, s.obs_number, (s.n_obs_alloc)*sizeof(int)); + obs_number = s.obs_number; } @@ -220,30 +213,19 @@ return; /////////////////////////////////////////////////////////////////////////////// -void FcstObsSet::extend(int * & a, int & n_alloc, const int N) +void FcstObsSet::extend(std::vector & a, int & n_alloc, const int N) { if ( N <= n_alloc ) return; -int j, k; -int * u = 0; - -k = N/fcst_obs_set_alloc_inc; +int k = N/fcst_obs_set_alloc_inc; if ( N%fcst_obs_set_alloc_inc ) ++k; k *= fcst_obs_set_alloc_inc; -u = new int [k]; - -if ( a ) memcpy(u, a, n_alloc*sizeof(int)); - -for (j=n_alloc; j + + +/////////////////////////////////////////////////////////////////////////////// + + static const int fcst_obs_set_alloc_inc = 50; @@ -40,7 +46,7 @@ class FcstObsSet { void assign(const FcstObsSet &); - void extend(int * &, int & n_alloc, const int n_new); + void extend(std::vector &, int & n_alloc, const int n_new); public: @@ -48,8 +54,8 @@ class FcstObsSet { // data // - int * fcst_number; // allocated - int * obs_number; // allocated + std::vector fcst_number; + std::vector obs_number; int n_fcst; int n_obs; @@ -96,8 +102,6 @@ extern std::ostream & operator<<(std::ostream &, const FcstObsSet &); /////////////////////////////////////////////////////////////////////////////// -// static const int max_fcst_obs_sets = 300; - static const int set_alloc_inc = 50; @@ -118,7 +122,7 @@ class SetCollection { // data // - FcstObsSet * set; // allocated + std::vector set; int n_sets; From e91357027367ed8943f54acf0a1e00c1ef26fde2 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 20 Feb 2023 10:52:14 -0700 Subject: [PATCH 15/16] Per #2402, rollback changes to set.h/.cc which continue to cause runtime errors in MODE. --- src/libcode/vx_shapedata/set.cc | 96 ++++++++++++++++++++++----------- src/libcode/vx_shapedata/set.h | 16 +++--- 2 files changed, 70 insertions(+), 42 deletions(-) diff --git a/src/libcode/vx_shapedata/set.cc b/src/libcode/vx_shapedata/set.cc index ec1c6fbabb..882aa29bd0 100644 --- a/src/libcode/vx_shapedata/set.cc +++ b/src/libcode/vx_shapedata/set.cc @@ -94,7 +94,9 @@ void FcstObsSet::init_from_scratch() { -n_fcst = n_obs = 0; +fcst_number = 0; + + obs_number = 0; all_clear(); @@ -113,13 +115,18 @@ void FcstObsSet::clear() { +// if ( fcst_number ) { delete [] fcst_number; fcst_number = 0; } +// if ( obs_number ) { delete [] obs_number; obs_number = 0; } + int j; -for (j=0; j 0 ) { +if ( s.n_fcst_alloc > 0 ) { extend_fcst (s.n_fcst_alloc); - fcst_number = s.fcst_number; + memcpy(fcst_number, s.fcst_number, (s.n_fcst_alloc)*sizeof(int)); } -if ( s.n_obs > 0 ) { +if ( s.n_obs_alloc > 0 ) { extend_obs (s.n_obs_alloc); - obs_number = s.obs_number; + memcpy(obs_number, s.obs_number, (s.n_obs_alloc)*sizeof(int)); } @@ -213,19 +220,30 @@ return; /////////////////////////////////////////////////////////////////////////////// -void FcstObsSet::extend(std::vector & a, int & n_alloc, const int N) +void FcstObsSet::extend(int * & a, int & n_alloc, const int N) { if ( N <= n_alloc ) return; -int k = N/fcst_obs_set_alloc_inc; +int j, k; +int * u = 0; + +k = N/fcst_obs_set_alloc_inc; if ( N%fcst_obs_set_alloc_inc ) ++k; k *= fcst_obs_set_alloc_inc; -a.reserve(k); +u = new int [k]; + +if ( a ) memcpy(u, a, n_alloc*sizeof(int)); + +for (j=n_alloc; j - - -/////////////////////////////////////////////////////////////////////////////// - - static const int fcst_obs_set_alloc_inc = 50; @@ -46,7 +40,7 @@ class FcstObsSet { void assign(const FcstObsSet &); - void extend(std::vector &, int & n_alloc, const int n_new); + void extend(int * &, int & n_alloc, const int n_new); public: @@ -54,8 +48,8 @@ class FcstObsSet { // data // - std::vector fcst_number; - std::vector obs_number; + int * fcst_number; // allocated + int * obs_number; // allocated int n_fcst; int n_obs; @@ -102,6 +96,8 @@ extern std::ostream & operator<<(std::ostream &, const FcstObsSet &); /////////////////////////////////////////////////////////////////////////////// +// static const int max_fcst_obs_sets = 300; + static const int set_alloc_inc = 50; @@ -122,7 +118,7 @@ class SetCollection { // data // - std::vector set; + FcstObsSet * set; // allocated int n_sets; From 516eced4c7be6b5147c866e30e5434763412c6f1 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 20 Feb 2023 21:48:54 -0700 Subject: [PATCH 16/16] Per #2402, fix CRC_Array assign function to just copy the vector instead of doing an element by element assignment. --- src/basic/vx_util/crc_array.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/basic/vx_util/crc_array.h b/src/basic/vx_util/crc_array.h index 8b34673c62..46f1642548 100644 --- a/src/basic/vx_util/crc_array.h +++ b/src/basic/vx_util/crc_array.h @@ -219,13 +219,7 @@ if ( a.Nelements == 0 ) return; extend(a.Nelements); -int j; - -for (j=0; j<(a.Nelements); ++j) { - - e[j] = a.e[j]; - -} +e = a.e; Nelements = a.Nelements;