I'm trying to convert some research-related code written in C by somebody I don't know and absolutely no documentation into C++. Basically converting T* and T** objects into vectors and more user-friendly containers.
Atm I have two variables,
double* data
double* references
I saw a trick here on SO that makes a regular vector easily assignable to the double*, like so:
references = &(*m_DataMaxPoints)[0];
so that's okay.
However, data* is supposed to be set from a std::vector<std::vector<double>>* m_Data;
I don't know how I should assign this.
I tried &(*m_Data)[0][0];
, but I really don't know what I should do here.
Any tips would be welcome.. :(
Edit 1: Original handling of data* in the C-program
double* data is declared in main()
int main(int argc, char *argv[])
{
FILE *infile;
int verbose_flag = FALSE;
double *data = NULL, *reference = NULL, *maximum = NULL;
int *cumsizes = NULL;
int nobj = 0, nruns = 0;
int k;
double volume = 0;
double time_elapsed;
read_input(stdin, "stdin", &data, &nobj, &cumsizes, &nruns);
read_input parses numbers from a text file into the arrays.
#define PAGE_SIZE 4096 // allocate one page at a time
#define DATA_INC (PAGE_SIZE/sizeof(double))
#define SET_INC 128 // assume 128 datasets (can grow)
int read_input(FILE *infile, const char *filename, double **datap, int *ncolsp, int **cumsizesp, int *nrunsp)
{
char b[2];
double number;
int newline; // last input was newline
int datai; // the current element of (*datap)
int col; // the column being read
int set = *nrunsp; // the current data set
int ncols = *ncolsp; // the number of columns
int datasize;
int setsize;
datai = (set == 0)
? 0
: ncols * (*cumsizesp)[set-1];
setsize = (set == 0)
? 0
: ((set-1) / SET_INC + 1) * SET_INC;
*cumsizesp = realloc(*cumsizesp, setsize * sizeof(int));
datasize = (datai == 0)
? 0
: ((datai - 1) / DATA_INC + 1) * DATA_INC;
*datap = realloc(*datap, datasize * sizeof(double));
// remove leading whitespace
fscanf (infile, "%*[ \t\n]");
if (feof(infile)) {
warnprintf("%s: file is empty.", filename);
return -1;
}
do {
newline = 0;
if (set == setsize) {
setsize += SET_INC;
*cumsizesp = realloc(*cumsizesp, setsize * sizeof(int));
}
(*cumsizesp)[set] = (set == 0) ? 0 : (*cumsizesp)[set-1]; // beginning of data set
while (newline == 0) {
col = 0; // beginning of row
while (newline == 0) {
if (fscanf(infile, "%lf", &number) != 1) {
char buffer[64];
fscanf(infile, "%60s", buffer);
errprintf(
"could not convert string `%s' to double, exiting...",
buffer);
}
if (datai == datasize) {
datasize += DATA_INC;
*datap = realloc(*datap, datasize * sizeof(double));
}
(*datap)[datai++] = number;
#if DEBUG > 2
fprintf(stderr, "set %d, row %d, column %d, x = %g\n",
set, (*cumsizesp)[set], col, number);
#endif
col++; // new column
fscanf(infile, "%*[ \t]");
newline = fscanf(infile, "%1[\n]", b);
}
if (!ncols)
ncols = col;
else if (col != ncols) {
if ((*cumsizesp)[0] == 0)
errprintf ("reference point has dimension %d"
" while input has dimension %d",
ncols, col);
else
errprintf("row %d has different length (%d)"
" than previous rows (%d), exiting...",
(*cumsizesp)[set], col, ncols);
}
(*cumsizesp)[set]++;
fscanf (infile, "%*[ \t]");
newline = fscanf (infile, "%1[\n]", b);
}
#if DEBUG > 1
fprintf (stderr, "Set %d, %d rows in total\n", set, (*cumsizesp)[set]);
#endif
set++; // new data set
fscanf (infile, "%*[ \t\n]");
} while (!feof(infile));
*ncolsp = ncols;
*nrunsp = set;
return 0;
}
What I am trying to do is convert as little as possible to C++ to make it easier to use and implement it into a larger project by making a wrapper class for this interface.
So, the file parsing and data allocation is done with vectors (they don't need to be pointers).
After parsing, I'd prefer to convert the vectors into C-style arrays so that I can call the original code's function without having to add vector to support to all of that, because I don't understand how to read it in pure C (multi-objective evolutionary algorithm implementation).
The original code finally calls:
volume = hv(data, nobj, cumsizes[nruns-1], reference);
While I'd like to do this:
double* data = &(*m_Data)[0][0]; // my 2d vector<double>
double* references = &(*m_DataMaxPoints)[0]; // 1d vector<double>
int cumsizes = m_Data->at(0).size();
m_Volume = hv(data, Objectives(), cumsizes, references);