I am working on a homework assignment with a few specific requirements. There must be a class named TestScores that takes an array of scores as its argument. It throws an exception if any scores are negative or greater than 100. Finally, it must have a member function that returns an average for all the scores. I wasn't clever enough to find a way to only pass the array into the constructor, so I also added in an int that tells the size of the array.
Running the code (I haven't even gotten around to testing the exceptions yet), I keep getting a Segmentation fault error. Valgrind and gdb have been rather unhelpful, outputting messages like:
==9765== Jump to the invalid address stated on the next line
==9765== at 0x2200000017: ???
Even more mysteriously (to me at least), in the for loop in the client code, my incrementor, i, somehow gets bumped from 0 to a seemingly random two-digit number right after creating the TestScores object. In previous versions, before I started using rand() to populate the array, i just never incremented and did the infinite loop thing.
Here's the contents of TestScores.cpp:
#include <iostream>
using std::cout;
using std::endl;
#include "TestScores.h"
#include <stdexcept>
using std::runtime_error;
// Constructor.
TestScores::TestScores(int a[], int s):
_SIZE(s), _scores()
{
// Look at each item in a[], see if any of them are invalid numbers, and
// only if the number is ok do we populate _scores[] with the value.
for (int i = 0; i < _SIZE; ++i)
{
if (a[i] < 0)
{
throw runtime_error ("Negative Score");
}
else if (a[i] > 100)
{
throw runtime_error ("Excessive Score");
}
_scores[i] = a[i];
cout << _scores[i] << " ";
}
cout << endl;
}
// Finds the arithmetic mean of all the scores, using _size as the number of
// scores.
double TestScores::mean()
{
double total = 0;
for (int i = 0; i < _SIZE; ++i)
{
total += _scores[i];
}
return total / _SIZE;
}
// median() creates an array that orderes the test scores by value and then
// locates the middle value.
double TestScores::median()
{
// Copy the array so we can sort it while preserving the original.
int a[_SIZE];
for (int i = 0; i < _SIZE; ++i)
{
a[i] = _scores[i];
}
// Sort the array using selection sort.
for (int i = 0; i < _SIZE; ++i)
{
int min = a[i];
for (int j = i + 1; j < _SIZE; ++j)
{
if (a[j] < min)
{
min = a[j];
a[j] = a[i];
a[i] = min;
}
}
}
// Now that array is ordered, just pick one of the middle values.
return a[_SIZE / 2];
}
And here's the client code:
#include <iostream>
#include "TestScores.h"
#include <stdexcept>
#include <cstdlib>
#include <ctime>
using std::exception;
using std::cout;
using std::endl;
int main()
{
const int NUM_STUDENTS = 20,
NUM_TESTS = 4;
int test [NUM_TESTS][NUM_STUDENTS];
// Make random seed to populate the arrays with data.
unsigned seed = time(0);
srand(seed);
// Populate the scores for the individual tests graded for the semester.
// These will all be values between 0 and 100.
for (int i = 0; i < NUM_TESTS; ++i)
{
for (int j = 0; j < NUM_STUDENTS; ++j)
{
test[i][j] = rand() % 100;
cout << test[i][j] << " ";
}
cout << endl;
}
// Now we have the data, find the mean and median results for each test.
// All values should be valid, but we'll handle exceptions here.
for (int i = 0; i < NUM_TESTS; ++i)
{
cout << "For Test #" << i + 1 << endl;
try
{
cout << "i = " << i << endl; // i = 0 here.
TestScores results(test[i], NUM_STUDENTS);
cout << "i = " << i << endl; // i = some random number here.
cout << "Mean: " << results.mean() << endl;
cout << "Median:" << results.median() << endl << endl;
}
catch (exception &e)
{
cout << "Error, invalid score: " << e.what() << endl;
}
cout << "For Test #" << i + 1 << endl;
}
return 0;
}
Edit:
The header was requested as well:
#ifndef TEST_SCORES_H
#define TEST_SCORES_H
class TestScores
{
private:
const int _SIZE;
int _scores[];
public:
// Constructor
TestScores(int a[], int);
double mean() const,
median() const;
};
#endif
I played around with making the array dynamic, and didn't initialize the array as empty, which fixed my problems, so that's what I ended up turning in. That leads me to a few follow-up questions.
Before going dynamic, I played around with initializing the array, _scores, by trying to give it the size value that was supposed to already be initialized. This led to compiler problems. I talked with my teacher about that, and he said that you can't allocate space for an array unless there's a hardwired global constant. That is, you can't pass a size value in the constructor to initialize an array. Is that true, and if so, why?
Stepping back a bit, it seems to me that dynamic arrays are better if you need a lot of values, because then you don't need a contiguous block of space in memory. So if you are making small arrays, it seems like a waste of space and time typing to make dynamic arrays. Is this untrue? Should I be doing all arrays from now on as dynamic? This experience certainly changed my opinion on the utility of regular arrays, at least as they pertain to classes.
Also, though I got full credit on the assignment, I feel like I violated the spirit by passing an argument for size (since the literal problem statement reads: "The class constructor should accept an array of test scores as its argument"). Aside from a hardwired global constant or having a size argument, is there a way to pass just the array? I swear I spent a good hour trying to think of a way to do this.
It seems you don't initialize _scores at all. You need _scores = new int[s]; at the top of the constructor (and also delete[] s; in the destructor).
Without initializing _scores, you write things to undefined memory locations.
Without TestScores.h one has to guess, but given what you say about the value of i being corrupted in the loop where you're creating the TestScores objects, that points to your _scores member variable not being properly initialized and when you're trying to load it you are actually trashing memory.
Once TestScores.h is visible, I'll revisit this answer taking the file into account.
Updated now that TestScores.h is available.
The problem is that you are not initializing _scores. You are not actually allocating any memory to hold the array, let alone setting the pointer to point to that memory. So when you attempt to store things into the array you're just trashing memory somewhere.
The first line in your constructor should be:
_scores = new int[_SIZE];
That will allocate memory to hold _SIZE ints and set _scores to point to that memory. Then your assignments to _scores[i] will actually go into defined memory belonging to your program.
Of course, you also have to release this memory (C++ won't do it for you) when instances of TestScore get destroyed. So you will need to define and implement a destructor for TestScores and that destructor needs to contain the line:
delete [] _scores;
This will free the block of memory that _scores points to. You can read docs on the delete operation to see why the [] have to be there in this case.
Related
For this assignment, I need to make a sorted copy of an array the user has given values to. All of my code works as intended, except for this specific part. I need this function (sortedCopy) to print out the sorted version of their array, without actually changing the array itself. As far as I can tell, to do so I need to used a constant version of the array in the function so the prototype would be something like: int *sortedCopy(const int *array, int size), but all this does is give the error shown in the title. Specifically:
main.cpp:72:29: error: assignment of read-only location '*(array +
((sizetype)(((long unsigned int)i) * 4)))' array[i] = array[min]
and it does this error twice, except with array[min] = temp; at the end instead
This is the code used, with the relevant parts of main:
#include <iostream>
using namespace std;
int* sortedCopy(const int *array, int size) {
int i, j, min, temp;
for (i = 0 ; i < size - 1; i++) {
min = i;
for (j = i + 1; j < size; j++) {
if (array[j] < array[min]) {
min = j;
}
}
temp = array[i];
array[i] = array[min];
array[min] = temp;
}
cout << "Sorted array is: " << endl;
for(int i = 0; i < size; i++) {
cout << array[i] << " ";
}
cout << endl;
// Not sure if I need to return anything or not either
}
int main() {
cout << "Please enter the size of the array." << endl;
int arraySize;
int array[arraySize];
cin >> arraySize;
cout << "Please enter integer values until the array is filled." << endl;
for (int i = 0; i != arraySize; i++) {
cout << "Value " << (i + 1) << ": ";
cin >> array[i];
cout << endl;
sortedCopy(array, arraySize);
for (int i = 0; i != arraySize; i++) { // I want this part to print the
cout << array[i] << " "; // original array entered by the user
}
}
If I remove the const part of the function, it works totally fine, except it will print the sorted array after the function is called, instead of the original array.
Firstly, C/C++ is best read "top-down":
int arraySize;
int array[arraySize]; // arraySize is undefined here!!
cin >> arraySize;
On the second line, ArraySize, might be 1, or 0, or -1000. You haven't defined it until line 3.
Also, C++ doesn't allow you to allocate arrays of variable size (unless that size is const [ so it is known at compilation time]):
int array[4];
The above is fine. This helps the operating system know how much memory to provide for you on the stack (it needs to do this before your programme starts running).
const int arraySize = 4;
int array[arraySize];
Because the C++ compiler knows that arraySize is 4, it processes this just like the above code, so this is also fine.
So to handle arrays of genuinely variable length (length that depends on inputs), you need to first read the user inputs, then use dynamic allocation ("new", or a container that does dynamic allocation for you, like a vector).
As for the problem with "const", what I think that you need to understand here is that "const" is really just a promise from the programmer: The programmer is communicating to the compiler (and any programmers reading the code) that this data is not supposed to change. All the compiler does is check whether you keep your promise (or if you send it to another function / pointer that doesn't hold that promise). So by using "const" there is no work done being done for you to actually keep the data constant - just that it will complain if you don't do the work.
int* sortedCopy(const int *array, int size) {
Above you're flagging to the compiler that the sortedCopy function will keep the data in the array constant.
array[i] = array[min];
array[min] = temp;
And here (above) you are breaking that promise.
If you don't want to edit the original array, then the easiest solution is just to copy it before you send it to your sorting function.
What is the correct way to pass pointers to an array from one C++ program to another linked C++ program?
I have a C++ program and it calls a function named SaveGatheredVec() in another C++ program that is included using the header file. SaveGatheredVec() shall return a pointer to an array that I can print from the function I called. But when I do something like below, the pointer is not getting the correct address of the array and just prints Segmentation Fault.
AS THE CODE IS LITTLE MESSY AND A LOT OF THINGS ARE GOING ON, just looking at NodesVisited[] and pointer p is what I need help with. I even tried declaring a global variable in the cpp program from where I call SaveGatheredVec and pass the array to the function, but it still gives the same error.
#include<iostream>
#inlcude "AnotherC++Program.h"
...
main(){
BFS();
}
void BFS(PSpMat<ElementType>::MPI_DCCols D, PSpMat<ElementType>::MPI_DCCols B, int ACol, string output){
int *p=0;
PSpMat<ElementType>::MPI_DCCols C = Mult_AnXBn_DoubleBuff<PTDOUBLEDOUBLE, ElementType, PSpMat<ElementType>::DCCols>(D,B);
int64_t cnnz = C.getnnz();
ostringstream tinfo;
p=C.SaveGatheredVec(output);
for(int i=0; i<cnnz; i++)
cout << "\n-----" << *(p+i);// on return it says Segmentation Fault
}
SaveGatheredVec() is defined in another C++ program linked by a header as below:
#include<iostream>
...
template <class IT, class NT, class DER>
template <class HANDLER>
int * SpParMat< IT,NT,DER >::SaveGatheredVec( string filename, HANDLER handler, bool transpose) const
{
int proccols = commGrid->GetGridCols();
int procrows = commGrid->GetGridRows();
IT totalm = getnrow();
IT totaln = getncol();
//IT totnnz = getnnz();
IT totnnz = 1;
static int NodesVisited[1]; //for example purpose, this is made just of size 1
int increament=0;
int flinelen = 0;
ofstream out;
if(commGrid->GetRank() == 0)
{
std::string s;
std::stringstream strm;
strm << "%%MatrixMarket matrix coordinate real general" << endl;
strm << totalm << " " << totaln << " " << totnnz << endl;
s = strm.str();
out.open(filename.c_str(),ios_base::trunc);
flinelen = s.length();
out.write(s.c_str(), flinelen);
out.close();
}
int colrank = commGrid->GetRankInProcCol();
int colneighs = commGrid->GetGridRows();
...
for(int j = 0; j < 2; ++j)
{
IT rowcnt = 0;
sort(csr[j].begin(), csr[j].end());
int mysize = csr[j].size();
MPI_Gather(&mysize, 1, MPI_INT, gsizes, 1, MPI_INT, 0, commGrid->GetRowWorld());
if(commGrid->GetRankInProcRow() == 0)
{
rowcnt = std::accumulate(gsizes, gsizes+proccols, static_cast<IT>(0));
std::partial_sum(gsizes, gsizes+proccols-1, dpls+1);
ents = new pair<IT,NT>[rowcnt];
}
MPI_Gatherv(SpHelper::p2a(csr[j]), mysize, datatype, ents, gsizes, dpls, datatype, 0, commGrid->GetRowWorld());
if(commGrid->GetRankInProcRow() == 0)
{
for(int k=0; k< rowcnt; ++k)
{
if (!transpose){
//NodesVisited is assigned below
NodesVisited[increament]= j + roffset + 1; increament++;
out << j + roffset + 1 << "\t" << ents[k].first + 1 << "\t";
handler.save(out, ents[k].second, j + roffset, ents[k].first);}
else
{
out << ents[k].first + 1 << "\t" << j + roffset + 1 << "\t";
handler.save(out, ents[k].second, j + roffset, ents[k].first);
}
out << endl;
}
delete [] ents;
}
}
if(commGrid->GetRankInProcRow() == 0)
{
DeleteAll(gsizes, dpls);
out.close();
}
}
MPI_Barrier(commGrid->GetWorld());
}
for(int j=0; j<totnnz;j++)
cout << "\nHere" << NodesVisited[j]; //values are printed correctly here
return NodesVisited;
}
If someone can help with an example or some ideas how should I retrieve the values of an array from a function defined in another C++, it would be of great help as I have to use the function defined in another C++ function. Thanks.
What exactly do you mean by "different program"? Do you mean a different .cpp file? In that case that would be a different translation unit, and it doesn't really have any effect as to pointers - that is, you probably have a bug elsewhere.
If you meant a different programs as in a different process, then that isn't possible in user-mode. Each process has its own virtual address space, specifically designed and implemented in hardware and OS so that processes cannot access each other's memory.
Note: This is possible in kernel-mode drivers, where all drivers share the same virtual address space.
You should post more of your code, as it is very difficult to see what you are actually doing in fun, and what data structure your return pointer is pointing to. However, I would venture a guess that you are creating a local array - that is, in the stack - and returning a pointer to that. Stack variables get destroyed once they fall out of scope, which would explain why your pointer becomes invalid once the function returns.
Update:
In your SaveGatheredVec function, in the line static int NodesVisited[1];, static makes all the difference. Without it, NodesVisited would be in the stack and a pointer to it would be invalidated once the stack unwinds on function return. See The stack and the heap and this SO question.
However, because you used static it lives until the end of the program, and there isn't anything immediately obvious. Try printing the value of NodesVisited, the pointer, and of p in BFS, and check that they are the same. Also, check that totnnz in SaveGatheredVec and cnnz in BFS have the same value - they should both be 1 in your example. If cnnz is larger then you'll read out of bounds and cause the seg fault.
NodesVisited[increament]= j + roffset + 1; increament++;
increament[sic: increment] should never go above 0 in your example.
As #Ramon says you should put more code about fun() function. To use properly the int* pointer you first of all have to initialize it, and then create a space of memory where it points to, to copy the elements of the array you want in it.
So I am making a merge sort program in c++ that is supposed to take 5 arrays of size 10, 100, 1000, 10000, and 100000, and tell how many comparisons are made for each array. I was able to sort all arrays fine, but I ran into a stack overflow when trying to make a third object of my merge sort class. I made the first two objects of my merge sort class without any problems, but when I make a third object of my merge sort class, I get an error that there is a stack overflow. When I debug the program it points me to the .asm file, and since I don't know assembly I'm not sure what to think of this. I've run into this problem in the past, and it's because I forgot to dynamically allocate memory to array's. I looked back and all my array's have been dynamically allocated, so I'm not sure why I am getting this error. Here is my main, I marked what is giving me errors with asterisks. Any help is appreciated, this is my second question on here so don't destroy me please :)
//main.cpp
int main(){
int* tenArray;
int* hundArray;
int* thouArray;
int* tenThouArray;
int*oneHundThouArray;
tenArray = new int[9];
hundArray = new int[99];
thouArray = new int[999];
tenThouArray = new int[9999];
oneHundThouArray = new int[99999];
srand((unsigned int)time(NULL));
//Create arrays filled with random numbers
for (int i = 0; i < ARRAY_TEN; i++) {
tenArray[i] = rand();
}
for (int i = 0; i < ARRAY_HUND; i++) {
hundArray[i] = rand();
}
for (int i = 0; i < ARRAY_THOU; i++) {
thouArray[i] = rand();
}
for (int i = 0; i < ARRAY_TEN_THOU; i++) {
tenThouArray[i] = rand();
}
for (int i = 0; i < ARRAY_ONE_HUND_THOU; i++) {
oneHundThouArray[i] = rand();
}
MergeSort tenSort;
MergeSort hundSort;
//******************************************************************
MergeSort thouSort;//When typed the program will give an error
//******************************************************************
//Here I am just calling my sort function from implementation file:
//sorting 10 array
tenSort.sort(tenArray, 0, ARRAY_TEN - 1);
cout << endl << "Comparisons = " << tenSort.getCount() << endl;
//sorting 100 array
hundSort.sort(hundArray, 0, ARRAY_HUND - 1);
cout << endl << "Comparisons = " << hundSort.getCount() << endl;
//****************************************************************
//sorting thousand array
thouSort.sort(thouArray, 0, ARRAY_THOU - 1);
cout << "comparison = " << thouSort.getCount() << endl;
//****************************************************************
}
getCount just looks like this:
//in implementation
int MergeSort::getCount() {
return count;
}
If it helps the line in the asm file causing the error says:
test dword ptr[eax],eax ;probe page
Do the MergeSort constructors allocate any additional memory? It's possible you're actually running out of memory on the stack. The stack can only contain so much data, and declaring over a hundred-thousand integers multiple times could add up to quite a lot.
I'm hoping someone can shed some light on where I am going wrong with pointers.. I've read countless web pages and tried various things but for some reason my code is returning jibberish (which I'm guessing may be the memory addresses instead of the data within my array). The purpose of the program is to create an array of 100 elements on the heap, pass this array by a pointer to a function (along with two integer variables start and end); a new array will be created on the heap (this comprises of a chunk of the original array using the start and end variables) and the pointer to this array is passed back to the main method so that the new array can be outputted. My problem is not only is the output seeming to be the location not the value, but also it seems 100 values are outputted not 20 as should be expected. I've spent hours trying to figure out where I have gone wrong and just when I think I understand the concept of pointers my faith is destroyed by red squigglies and incorrect outputs. Please HELP! My code is as follows:
#include "stdafx.h"
#include <iostream>
#include <time.h>
using namespace std;
double* getSubArray(double*, int, int);// Declare a function that will get the sub array
int _tmain(int argc, _TCHAR* argv[])
{
const int size = 100;// Declare the size of the array
double* pA;// Declare the variable to hold the pointers to the data in array
double* pB;
int start = 15;
int end = 35;
pA = new double[size];// Create space for the array
srand(clock());// Seed the program to the computers current time so that random gets a different set of random numbers everytime it is run
// Use a for loop to traverse through each element of the array (starting at index 0) placing a number defined by the random function that is no higher than 250
for (int i = 0; i < size; i++)
{
pA[i] = rand()%250;
}
cout << "An Array of 100 numbers is created and stored in the heap, these values are:" << endl;
// Output the Array for the user to see
for (int j = 0; j < size; j++)
{
// Place 10 numbers on each line
if (j % 10 == 0)
{
cout << endl;
}
cout << *(pA + j) << " ";
}
cout << endl << "The program will build a second array using the data between the indexes " << start << " & " << end << endl;
pB = getSubArray(pA, start, end);// Pass the data to the method
// Output second array for user to compare
for (int k = 0; k < size; k++)
{
// Place 10 numbers on each line
if (k % 10 == 0)
{
cout << endl;
}
cout << *(pB + k) << " ";
}
system("pause");
return 0;
}
double* getSubArray(double* pA, int start, int end)
{
double* pB = new double[end-start];// Declare space in the heap for the new array whoes size is the size of the criteria given
for (int i = 0; i < (end - start); i++)
{
for (int j = start; j < end; j++)
{
*(pB + 0) = pA[j];
}
}
return pB;
}
*(pB + 0) = pA[j];
That keeps writing to the first element of the array. Surely you want to write to each element in turn:
for (int i = start; i < end; ++i) {
pB[i-start] = pA[i];
}
or if you don't want to write your own loop
std::copy(pA+start, pA+end, pB);
Don't forget to delete[] everything you new[] or, to save mucking around with low-level memory management, use std::vector to manage the dynamic arrays for you.
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)'
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.
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).