473,395 Members | 1,379 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

3D array to 2D ptr casting...

Say I had a three-dimensional array containing multiple 2D level data.

It might be defined like this:

unsigned char LEVEL_DATA[][5][5] = {
{
{1, 1, 1, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 1, 1, 1, 1}
}
};

Assume of course there are more dimensions and more than one level.

What is the proper way to cast to a 2D const ptr? This is what I did to
make the compiler shut up, but I don't know if it's correct or not.

const unsigned char * const *data =
reinterpret_cast<const unsigned char * const *>(LEVEL_DATA[0]);

Is this correct? I was reading
http://www.parashift.com/c++-faq-lit...html#faq-18.17
But it doesn't mention pre-defined array data specifically, and the
compiler doesn't implicitly treat them the same (yeah, I know they are
not the same).

Thanks,

--John Ratliff
Aug 27 '05 #1
4 1907
John Ratliff wrote:
Say I had a three-dimensional array containing multiple 2D level data.

It might be defined like this:

unsigned char LEVEL_DATA[][5][5] = {
{
{1, 1, 1, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 1, 1, 1, 1}
}
};

Assume of course there are more dimensions and more than one level.

What is the proper way to cast to a 2D const ptr? This is what I did to
make the compiler shut up, but I don't know if it's correct or not.

const unsigned char * const *data =
reinterpret_cast<const unsigned char * const *>(LEVEL_DATA[0]);

Is this correct? I was reading
http://www.parashift.com/c++-faq-lit...html#faq-18.17
But it doesn't mention pre-defined array data specifically, and the
compiler doesn't implicitly treat them the same (yeah, I know they are
not the same).


Well, the reinterpret_cast is clearly wrong.

I'm still not sure how to make a pointer to array data, but I changed my
code to avoid making one.

--John Ratliff
Aug 27 '05 #2
John Ratliff, I tried your example with and without const pointers and
found that although it compiled , it exhibited non-defined behavior at
run-time.
I checked in Margaret Ellis and Bjarne Strousup's ARM and they state :
"An array is one-dimensional : talking about multidimensional arrays in
C/C++ is simply referring to a conventional use of arrays of arrays."
With that advice in mind, I think an alternative might be to write a
C++ class implementing the three-dimensional array abstraction. Then,
in the class, you could write an member operator which converts a
three-dimensional array to a 2 dimensional const ptr.
Also, there is a boost library multi_array class which you can
either in a composition pattern or a single inheritance pattern. Thank
you.


John Ratliff wrote:
John Ratliff wrote:
Say I had a three-dimensional array containing multiple 2D level data.

It might be defined like this:

unsigned char LEVEL_DATA[][5][5] = {
{
{1, 1, 1, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 1, 1, 1, 1}
}
};

Assume of course there are more dimensions and more than one level.

What is the proper way to cast to a 2D const ptr? This is what I did to
make the compiler shut up, but I don't know if it's correct or not.
>

Is this correct? I was reading
http://www.parashift.com/c++-faq-lit...html#faq-18.17
But it doesn't mention pre-defined array data specifically, and the
compiler doesn't implicitly treat them the same (yeah, I know they are
not the same).


Well, the reinterpret_cast is clearly wrong.

I'm still not sure how to make a pointer to array data, but I changed my
code to avoid making one.

--John Ratliff


Aug 27 '05 #3
Frank Chang wrote:
John Ratliff, I tried your example with and without const pointers and
found that although it compiled , it exhibited non-defined behavior at
run-time.
I checked in Margaret Ellis and Bjarne Strousup's ARM and they state :
"An array is one-dimensional : talking about multidimensional arrays in
C/C++ is simply referring to a conventional use of arrays of arrays."
With that advice in mind, I think an alternative might be to write a
C++ class implementing the three-dimensional array abstraction. Then,
in the class, you could write an member operator which converts a
three-dimensional array to a 2 dimensional const ptr.
I thought about this, but that seemed like a lot of work.

Unless you had a different idea, I would either have to a) cast to a 1D
array and doing ptr math, or b) build a new 2D array using pointers from
the 3D array.

Since I got around using a new variable for the 2D array, I suppose it
doesn't matter.

And yeah, I got the same undefined behaviour. reinterpret_cast allowed
the cast, but didn't know what to do once it had done it.
Also, there is a boost library multi_array class which you can
either in a composition pattern or a single inheritance pattern. Thank
you.


I've heard a lot about boost. But since I got around converting my array
at all, I think I'll just leave it as is.

If I were reading the level data from file instead of having them
already pre-defined in the code, I could do something like this:

-------------
#include <iostream>

unsigned char LEVEL_DATA[][5][5] = {
{
{1, 1, 1, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 1, 1, 1, 1}
}
};
class LevelData {
private:
unsigned char ***LEVEL_DATA;

public:
LevelData();
~LevelData();
const unsigned char * const *getData(int level) const;
};

inline const unsigned char * const *LevelData::getData(int level) const {
return
static_cast<const unsigned char * const *>(LEVEL_DATA[level]);
}

LevelData::LevelData() {
LEVEL_DATA = new unsigned char **;
LEVEL_DATA[0] = new unsigned char *[5];

for (int i = 0; i < 5; i++) {
LEVEL_DATA[0][i] = new unsigned char[5];
}

for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
LEVEL_DATA[0][y][x] = ::LEVEL_DATA[0][y][x];
}
}
}

LevelData::~LevelData() {
for (int i = 0; i < 5; i++) {
delete [] LEVEL_DATA[0][i];
}

delete [] LEVEL_DATA[0];
delete LEVEL_DATA;
}

int main(int, char **) {
LevelData levels;
const unsigned char * const *data = levels.getData(0);

for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
std::cout << static_cast<int>(data[y][x]) << ' ';
}

std::cout << '\n';
}

return 0;
}
--------------

Except, you know, the ::LEVEL_DATA would be coming from a file.

--John Ratliff
Aug 28 '05 #4
John, I believe your solution is an elegant one. I haven't tested it
yet. Yesterday, I wrote to you:

" I think an alternative might be to write a
C++ class implementing the three-dimensional array abstraction. Then,
in the class, you could write an member operator which converts a
three-dimensional array to a 2 dimensional const ptr."

I think your class differs from my proposed class principally in the
respect that you use the getData(int) member function instead of an
member operator()[int] to cast a 3D array to an const 2D pointer. I
think the stumbling block was that you and I were trying to directly
convert from unsigned char LEVEL_DATA[][5][5] = {
{
{1, 1, 1, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 1, 1, 1, 1}
}
};
to a const 2D pointer. I like how you circumvented that problem by
using a member variable, unsigned char ***LEVEL_DATA, in your
LevelData class. I will have to remember your solution in case I ever
need to do something similar in the future. Thank you for the reply.

Aug 28 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

38
by: VK | last post by:
Hello, In my object I have getDirectory() method which returns 2-dimentional array (or an imitation of 2-dimentional array using two JavaScript objects with auto-handled length property - please...
11
by: truckaxle | last post by:
I am trying to pass a slice from a larger 2-dimensional array to a function that will work on a smaller region of the array space. The code below is a distillation of what I am trying to...
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
4
by: gg9h0st | last post by:
i'm a newbie studying php. i was into array part on tutorial and it says i'll get an array having keys that from member variable's name by converting an object to array. i guessed "i can...
9
by: Brian Tkatch | last post by:
I'm looking for a simple way to unique an array of strings. I came up with this. Does it make sense? Am i missing anything? (Testing seems to show it to work.) Public Function Unique(ByVal...
18
by: Kyro | last post by:
New to C# (migrating from Delphi) and I'm not sure how to get a delimited string into an array of string. input: string looks like - 01-85-78-15-Q11 output: an array with elements - ...
15
by: Madhur | last post by:
Hi All, I would like you help me in creating an array of data types. I am interested in look at the the data type which looks like this Array...
14
by: KK | last post by:
Dear All I have a small problem with using as operator on value type array. Here is an example what I am trying to do. using System; using System.Collections.Generic; using System.Text;
152
by: vippstar | last post by:
The subject might be misleading. Regardless, is this code valid: #include <stdio.h> void f(double *p, size_t size) { while(size--) printf("%f\n", *p++); } int main(void) { double array = { {...
9
by: Slain | last post by:
I need to convert a an array to a multidimensional one. Since I need to wrok with existing code, I need to modify a declaration which looks like this In the .h file int *x; in a initialize...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.