3D Arrays

  • Thread starter Thread starter Mike C#
  • Start date Start date
M

Mike C#

OK, brain freeze (don't laugh). Stupid question, but how do I dynamically
declare and initialize a 3-D array in C++? Here's what I want:

Array with 2000 elements
|
|--------Array with 38 elements
|
|-----------Array of 256 TCHARs

It's supposed to represent 2000 rows of 38 columns, each a 256-wchar_t
string.

Thanks.
 
Mike said:
OK, brain freeze (don't laugh). Stupid question, but how do I dynamically
declare and initialize a 3-D array in C++? Here's what I want:

Array with 2000 elements
|
|--------Array with 38 elements
|
|-----------Array of 256 TCHARs

It's supposed to represent 2000 rows of 38 columns, each a 256-wchar_t
string.

Thanks.

If you can use Boost (www.boost.org), your best bet would be :
boost::multi_array<wchar_t, 3> MyArray (boost::extents[2000][38][256]);

Otherwise, you should use std::vector :
typedef <std::vector<std::vector<std::vector<wchar_t > > > ArrayType;
ArrayType MyArray (2000);
//double loop to resize internal vectors....

Of course, there is also the "C-style" definition, but it is
error-prone, especially if you must pass the array as a function
parameter, since you will then loose size information :

wchar_t MyArray [2000][38][256];

Arnaud
MVP - VC
 
If you can use Boost (www.boost.org), your best bet would be :
boost::multi_array<wchar_t, 3> MyArray (boost::extents[2000][38][256]);

Otherwise, you should use std::vector :
typedef <std::vector<std::vector<std::vector<wchar_t > > > ArrayType;
ArrayType MyArray (2000);
//double loop to resize internal vectors....

Great! I need a little further guidance: once I implement either of these
options, how do I pass the arrays to ODBC functions that are expecting
C-style arrays of strings?
Of course, there is also the "C-style" definition, but it is
error-prone, especially if you must pass the array as a function
parameter, since you will then loose size information :

wchar_t MyArray [2000][38][256];

Hmm. Do I really want to increase the stack size to accomodate the 38 MB
required for this non-dynamic method? As mentioned, I want to "dynamically"
declare and initialize a 3-D array (i.e., "new" and "delete"). Since I'm
calling ODBC functions that are using these arrays, and they are expecting
the "error-prone C-style" arrays, I'd prefer to use them.

Thanks.
 
Mike said:
If you can use Boost (www.boost.org), your best bet would be :
boost::multi_array<wchar_t, 3> MyArray (boost::extents[2000][38][256]);

Otherwise, you should use std::vector :
typedef <std::vector<std::vector<std::vector<wchar_t > > > ArrayType;
ArrayType MyArray (2000);
//double loop to resize internal vectors....

Great! I need a little further guidance: once I implement either of these
options, how do I pass the arrays to ODBC functions that are expecting
C-style arrays of strings?

If you need C-style array binary compatibility, std::vector won't work
: You need to use boost::multi_array or std::valarray (but I believe
valarray API is more difficult to grasp).

To access the raw data of a multi_array, use multi_array::data.
Of course, there is also the "C-style" definition, but it is
error-prone, especially if you must pass the array as a function
parameter, since you will then loose size information :

wchar_t MyArray [2000][38][256];

Hmm. Do I really want to increase the stack size to accomodate the 38 MB
required for this non-dynamic method? As mentioned, I want to "dynamically"
declare and initialize a 3-D array (i.e., "new" and "delete"). Since I'm
calling ODBC functions that are using these arrays, and they are expecting
the "error-prone C-style" arrays, I'd prefer to use them.

Can't you declare the object either as static-duration, either as
member of a class?

Arnaud
MVP - VC
 
If you need C-style array binary compatibility, std::vector won't work
: You need to use boost::multi_array or std::valarray (but I believe
valarray API is more difficult to grasp).

To access the raw data of a multi_array, use multi_array::data.

I don't have Boost, and I checked on it: I cannot install/use Boost library
here. The std::valarray doesn't appear to return a C-style array (not
negotiable).
Can't you declare the object either as static-duration, either as
member of a class?

The object? static-duration? I must be dense this morning, cause I'm not
seeing how that gets me from point A (no array) to point B (a 39x200x256
three-dimensional dynamic whcar_t array)?

I'm calling ODBC functions here and they require C-style arrays. Here's a
link to the function I'm trying to work with now:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcsqlbindparameter.asp.
I have no intention of re-writing the SQL Server ODBC drivers to make them
work with std::vector, std::valarray or any other C++ objects or templates.

I'm attempting to use the SQL_PARAMETER_BIND_BY_COLUMN binding type, which
requires two C-style arrays for each parameter: one C-style array for the
values and a second C-style array for the length/indicator. Since I have 39
parameters, I thought it would be useful to set them up as two 39 column
arrays as opposed to 78 separate arrays. Looks like the best option is to
just bite the bullet and set up 78 separate one-dimensional C-style arrays
and be done with it. Then repeat for the other 13 items that I'm trying to
do parameter binding on.

Thanks.
 
Mike said:
OK, brain freeze (don't laugh). Stupid question, but how do I dynamically
declare and initialize a 3-D array in C++? Here's what I want:

Array with 2000 elements
|
|--------Array with 38 elements
|
|-----------Array of 256 TCHARs

It's supposed to represent 2000 rows of 38 columns, each a 256-wchar_t
string.

You mean something like this?

wchar_t*** pointerTo2000ElementArray = new wchar_t**[2000];
for(int i = 0; i < 2000; i++) {
wchar_t** pointerTo38ElementArray = new wchar_t*[38];
for(int j = 0; j < 38; j++) {
pointerTo38ElementArray[j] = new wchar_t[256];
}
pointerTo2000ElementArray = pointerTo38ElementArray;
}
 
Yep, that's the one. Thanks Ray.

Ray said:
Mike said:
OK, brain freeze (don't laugh). Stupid question, but how do I
dynamically declare and initialize a 3-D array in C++? Here's what I
want:

Array with 2000 elements
|
|--------Array with 38 elements
|
|-----------Array of 256 TCHARs

It's supposed to represent 2000 rows of 38 columns, each a 256-wchar_t
string.

You mean something like this?

wchar_t*** pointerTo2000ElementArray = new wchar_t**[2000];
for(int i = 0; i < 2000; i++) {
wchar_t** pointerTo38ElementArray = new wchar_t*[38];
for(int j = 0; j < 38; j++) {
pointerTo38ElementArray[j] = new wchar_t[256];
}
pointerTo2000ElementArray = pointerTo38ElementArray;
}


 
Back
Top