As this is my first post on cplusplus.com, first of all thank you in advance for the help I anticipate receiving from other members. I am a retired chemist who is studying Visual C++ as a hobby to keep what passes for a brain active. I am still using VC++ 6.0 because the cost of the latest version is prohibitive for my limited uses.
I am developing a program which data is entered into a 2 dimensional array (raw_data[30][100]) defined at compile time. I have constructed a dialog box (CEditRawDataDlg) to edit the raw data in case of error in inputting the data. The dialog box asks the user for the row and column number of the incorrect datum and displays the current value in the dialog box. I have achieved this by declaring a reference (&m_pRaw_Data) to raw_data[0][0] (in the document class) in the dialog box class. By invoking the EN_CHANGE I can get the current value of raw_data[rows][columns] using *(m_pRaw_Data + (30 * m_row) + m_col). This works fine for the array declared at compile time.
I now want to use dynamically declared two dimensional array using the vector method. I have hit a problem since the dynamically declared array rows are not contiguous and leads to garbage values being returned (apart from the first row). Has anyone any idea how I might overcome this problem? I’ve tried lots of things but have not succeeded. Please be gentle with me guys because I’m just starting to learn. Thank you in advance.
Allan
declaring a reference (&m_pRaw_Data) to raw_data[0][0] (in the document class)
Based on what follows, it sound as if you've declared a pointer to the first element of the array (since you were able to add (30 * m_row) + m_col and then dereference the result). Make sure to not confuse references with pointers, and post actual lines of code.
I can get the current value of raw_data[rows][columns] using *(m_pRaw_Data + (30 * m_row) + m_col)
There are plenty of ways to make m_pRaw_Data[m_row][m_col] work even with arrays, and if you're using vectors of vectors, that would be the normal access. Can't you make the vector of vectors a member of your class?
(as for matrix libraries, boost.ublas and Eigen are popular)
Further to my question of yesterday, here is some more information about the actual coding. I am using the MFC Document/View architecture. I included the following in the document header file.
#include<vector>
using std::vector;
In the document cpp file I declared the 2 dimensional array using the following code in a separate function where I declare other arrays. This function is called when I either read raw data from file or create a new analysis and add raw data.
vector<vector<double> > raw_data;
int width = m + 2; // 2 more columns needed for subsequent processing
int height = n + 2; // 2 more rows needed for subsequent processing
raw_data.resize(height);
for(int i = 0; i < height; i++)
{
raw_data[ i ].resize(width);
}
The article in cplusplus.com uses the format raw_data<i>.resize(width) but when I try to compile the program using this format I get error C2673 binary '<' : no operator defined which takes a left-hand operand of type 'class std::vector<class std::vector<double,class std::allocator<double> >,class std::allocator<class std::vector
<double,class std::allocator<double> > > >' (or there is no acceptable conversion).
On running the program in debug mode I have TRACE’d the output for a run involving 4 samples of 3 variables with the following result.
As you can see, the columns are contiguous with 8 bytes difference in their addresses. The rows are all over the place and I cannot discern a pattern.
Tath, thanks for your input. I went to the link you suggested but could not follow the logic. Have you any other insights please? Also, I downloaded the latest two versions of Visual Studio Express but due to a bug, the latest version would not convert my versions written in V6.0. Furthermore, I believe that these versions do no support MFC unless I paid for the full editions.
Well, double type is 8 bytes long. How did you except addressing to be?
That's exactly as I'd expect it to be. My problem was that the columns weren't contiguous in memory and this is what caused my the problems. I've managed to find a way round this problem. I don't think the solution was very elegant but it works! I copied the raw_data[][] array in the Document to the Dialog box and got the data from this.
Thanks once again for your help. No doubt I'll be back when I hit the next snag.
when you create double array dynamically, array elements will never be contiguous in memory since this array will be array of pointers, ie.:
1 2 3 4 5
int *asd[2]; //these pointers are contiguous
//these arrays are not contiguous since they are assigned random heap address
asd[0] = newint [2]; //some random place
asd[1] = newint[3]; //some random place
You need to create 1d array (like vector) but access it like 2d.
Thanks a lot tath. I tried this but found that first element of the matrix i.e. a.at(0,0) is not initialized properly. I tried this->pData = NULL in the ctor and it works now.
@vineshgada
it was like that because this->pData = new T[1] create array, but dont initialize any data in it. For simple data like int, floati could simply write:
1 2
this->pData = new T[1];
this->pData[0] = 0;
but for objects like classes not always can be assigned 0;
thats why after creating matrix i assigned 1st value manually:
1 2
matrix<int> a;
a.at(0) = 2;
It can be done nicely by creating constructor with parameter