0

I am working on a program that reads in altitude values from a file into a 2-D array, a matrix, and I am trying to pass that array to another function that finds the maximum value. I understand that, by default, arrays are passed by reference, but I am not trying to change the values of the array in the function so this shouldn't matter much. I have gone through several pages about calling arrays but I haven't been able to find any mention of the type of error I am getting when I compile the code. The problem seems to be in the number of arguments that are called or the way in which the are called, but I can't see any discrepancies in the various appearances of the function. My guess is there is something about passing a 2-D array that I wasn't told in class and that I haven't learned yet on my own. Any help would be greatly appreciated. The code is:

#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

// First instance of function declaration
double find_max(double elevations[][3600], double ilat, double ilon, int nlat, int nlon);

int main(int argc, char *argv[]) {

// Declare program variables
double lat_init, lon_init;
double lat_res, lon_res;
double peak, valley;
int lon_col, lat_row;
string indat, inpoints;
.
.
.
double elevations[lat_row][lon_col];

// Open and read topographic data file
ifstream topo_points;
topo_points.open(inpoints.c_str());

for (int i=0; i<lat_row; i++) {
    for (int j=0; j<lon_col; j++)
        topo_points >> elevations[i][j];
}

// Call function to find peak in the data
peak = find_max(elevations, lat_init, lon_init, lat_row, lon_col);

return 0;

}


// ***** Here lie the functions *****

// This function reads in the array of elevations, initial latitude and longitude
// of the data, and the number of data points and uses this information to find
// the latidude and longitude of the highest point on earth
double find_max(double elev[][3600], double ilat, double ilon, int nlat, int nlon) {

double num, max;
double latpos, lonpos;

max = 0;

for (int i=0; i<nlat; i++) {
    for (int j=0; j<nlon; j++) {
    num = elev[i][j];
    if (num > max) {
        max=num;
        latpos= ilat - i;
        lonpos= ilon + j;
    }
    }
}

cout << "The tallest peak on earth has an altitude of " << max;
cout << " and is located at " << latpos << "deg latitude and ";
cout << lonpos << "deg longitude";

return max;
}

However, when I call the function I get the following error:

error: cannot convert 'double (*)[(((long unsigned int)(((long int)lon_col) - 1)) + 1u)]' to 'double (*)[3600]' for argument '1' to 'double find_max(double (*)[3600], double, double, int, int)'

2 Answers2

1

From what i see in the code, there are a few glitches.

  • You have defined the array elevations as

    double elevations[lat_row][lon_col];

which isn't gonna work, because the size of the c-style arrays must be determinable during compile-time. And since lat_row and lon_col are variables, that's an error.

So, you could either use arrays with dynamic memory allocation, or std::vector, which in most cases is preferable. So, in your case you could have something like:

typedef std::vector< std::vector<double> > ElevationsType;
ElevationsType elevations;

and then just use that array or array of double. Then, your find_max function can be declared as:

double find_max(const ElevationsType &elevations, double ilat, double ilon);

Note that in this case you won't need to pass nlat and nlon, because you could just do:

ElevationsType::size_type nlat, nlon, i, j;
nlat = elevations.size();

for (i = 0; i != nlat; ++i) {
    nlon = elevations[i].size();
    for (j = 0; j != nlon; ++j) {
        const double element = elevations[i][j];
        // do whatever you need to do with the element
    }
}

Of course, if your arrays will have fixed size you could set it (std::vector::resize) once you create the object of type ElevationsType, or just allocate enough space (std::vector::reserve) and then initialize it. If it's large, that may increase performance.

However, if you choose to go with c-style arrays, it would be something like:

double **elevations = (double **)malloc(sizeof(double*) * lat_row);
for (size_t i = 0; i != lat_row; ++i) {
    elevations[i] = (double*)malloc(sizeof(double) * lat_col);

    // initialize the elements
    for (size_t j = 0; j != lat_col; ++j) {
        elevations[i][j] = 100.0; /* your value */
        std::cout << "elevations[" << i << "][" << j << "] = " << elevations[i][j] << std::endl;
    }
}

which is more tedious for many people.. so to speak. And if you go in that route, just don't forget to deallocate all allocated memory with free().

you could also use the c++ new operator to allocate the memory, but the principle is pretty much the same.

So I'd suggest you to use the std::vector. It's easier to work with, at least if you have limited experience. It will also take care of memory allocation/deallocation, and that causes many bad things, overflows, leaks, etc. which will be avoided if you use the vector.

Amy
  • 1,814
  • 2
  • 23
  • 38
  • Thanks so much for the answer! I found that as soon as I set the array size using integer values instead of program variables that the call function worked fine. I am still a bit new to c++ and although I've tried using vectors in the past, I'm not totally familiar with them. This seems like a good opportunity to get better! – user1263011 Mar 12 '12 at 03:26
  • Yes, stick with "std::vector" to avoid the difficulties of working with C-style arrays (pointers, etc.). It's still useful know though (C-style arrays), and if you have the time there are plenty of articles around on the subject. See my two recent posts in this forum for starters: http://stackoverflow.com/questions/9583086/2dimensional-array-pointer-manipulation-in-c/9608139#9608139 and http://stackoverflow.com/questions/9672731/manipulating-multidimensional-arrays-with-functions-in-c/9677552#9677552 – Larry Mar 13 '12 at 14:57
0

You're trying to pass an array whose size is determined dynamically (i.e. at runtime), and pass it to a function which expects the array to have its 2nd dimension determined at compile time to be 3600 (which seems like a pretty reasonable thing to complain about, actually).

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101