|
|
This thread is locked; no one can reply to it.
|
1
2
|
| Declaring 3d array using new/typedef. |
|
verthex
Member #11,340
September 2009
|
Cookies to whoever solves this one. I found the following code on this page and I'm wondering how to modify it to 3d? I also don't get the typedef part since I never use typedefs. #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { typedef double (array5k_t)[5000]; array5k_t *array5k = new array5k_t[5000]; array5k[4999][4999] = 10; printf("array5k[4999][4999] == %f\n", array5k[4999][4999]); return 0; } edit: Oh and how do I delete the whole thing.
|
|
William Labbett
Member #4,486
March 2004
|
A guess :- array5k_t **array5k = new (array5k_t *)[5000]; int i; for(i = 0; i < 5000; ++i) { array5k[i] = new (array5k_t)[5000]; }
|
|
verthex
Member #11,340
September 2009
|
I tried this: 1#include <stdio.h>
2#include <stdlib.h>
3
4int main(int argc, char **argv)
5{
6
7 typedef double (array5k_t)[5000];
8
9 array5k_t **array5k = new (array5k_t*)[5000];
10
11 for(i = 0; i < 5000; ++i)
12 {
13 array5k[i] = new (array5k_t)[5000];
14 }
15
16 array5k[0][0][0] = 0;
17
18 std::cout<<array5k[0][0][0]<<std::endl;
19
20return 0;
21}
These were the errors In function 'int main(int, char**)':| I also tried this 1#include <stdio.h>
2#include <stdlib.h>
3
4int main(int argc, char **argv)
5{
6
7 typedef double (array5k_t)[5000];
8
9 array5k_t **array5k = new array5k_t *[5000];
10
11 for(int i = 0; i < 5000; ++i)
12 {
13 array5k[i] = new (array5k_t)[5000];
14 }
15
16 array5k[0][0][0] = 0;
17
18 std::cout<<array5k[0][0][0]<<std::endl;
19
20return 0;
21}
|
|
William Labbett
Member #4,486
March 2004
|
1#include <stdio.h>
2#include <stdlib.h>
3#include <iostream>
4
5using namespace std;
6
7
8int main(int argc, char **argv)
9{
10 int i; // must declare i to use it later
11
12 typedef double array5k_t[5000];
13
14 array5k_t **array5k = new array5k_t *[5000];
15
16 for(i = 0; i < 5000; ++i)
17 {
18 array5k[i] = new array5k_t [5000];
19 }
20
21 array5k[0][0][0] = 1000;
22
23 std::cout<<array5k[0][0][0]<<std::endl;
24
25 return 0;
26}
That any better ? I thought the brackets in the typedef were wrong. There might something wrong with the lines which use 'new' here I think. //editted
|
|
Oscar Giner
Member #2,207
April 2002
|
I'd just get rid of that typedef and do it the normal way: 1double ***array3d;
2array3d = new double**[5000];
3
4for(i=0; i<5000; ++i)
5{
6 array3d[i] = new double*[5000];
7 for(j=0; j<5000; ++j)
8 {
9 array3d[i][j] = new double[5000];
10 }
11}
12
13array3d[4999][4999][4999] = 10;
14printf("array3d[4999][4999][4999] == %f\n", array3d[4999][4999][4999]);
15
16for(i=0; i<5000; ++i)
17{
18 for(j=0; j<5000; ++j)
19 {
20 delete[] array3d[i][j];
21 }
22 delete[] array3d[i];
23}
24delete[] array3d;
-- |
|
verthex
Member #11,340
September 2009
|
@William: @Oscar. Thanks, I know that already but I wanted to get sophisticated with the typedef usage. suggestions, unless you have 5000^3 double in ram use this instead: 1#include <stdio.h>
2#include <stdlib.h>
3#include <iostream>
4
5using namespace std;
6
7
8int main(int argc, char **argv)
9{
10 int i; // must declare i to use it later
11
12 typedef double array5k_t[50];
13
14 array5k_t **array5k = new array5k_t *[50];
15
16 for(i = 0; i < 50; ++i)
17 {
18 array5k[i] = new array5k_t [50];
19 }
20
21 array5k[0][0][0] = 1000;
22
23 std::cout<<array5k[0][0][0]<<std::endl;
24
25 return 0;
26}
|
|
anonymous
Member #8025
November 2006
|
The point is that you allocate an array of arrays all at once. It doesn't matter how many dimensions the array has. #include <stdio.h> #include <stdlib.h> int main() { typedef double array10_10_t[10][10]; array10_10_t *arr = new array10_10_t[20]; arr[15][2][0] = 10; printf("arr[15][2][0] == %f\n", arr[15][2][0]); delete[] arr; return 0; }
|
|
William Labbett
Member #4,486
March 2004
|
1#include <stdio.h>
2#include <stdlib.h>
3#include <iostream>
4
5using namespace std;
6
7
8int main(int argc, char **argv)
9{
10 int i; // must declare i to use it later
11
12 typedef double array5k_t[50];
13
14 array5k_t **array5k = new array5k_t *[50];
15
16 for(i = 0; i < 50; ++i)
17 {
18 array5k[i] = new array5k_t [50];
19 }
20
21 array5k[0][0][0] = 1000;
22
23 std::cout<<array5k[0][0][0]<<std::endl;
24
25 for(i = 0; i < 50; ++i)
26 {
27 delete[] array5k[i];
28 }
29
30 delete[] array5k;
31
32 return 0;
33}
You could also use something like typedef double (*ptr_to_array)[50]; typedef double *ptr_to_array 3d_array; 3d_array actual_array; for(i = 0; i < 50; ++i) { for(j = 0; j < 50; ++j) actual_array[j][i] = new double [50]; } Probaably doesn't work, but there's room for improvement on that code. /* EDIT */ no definitely doesn't work. actual_array need to be allocated some memory too. /* EDIT 2 */ Sorry. I aught to test it first.
|
|
verthex
Member #11,340
September 2009
|
anonymous said: The point is that you allocate an array of arrays all at once. It doesn't matter how many dimensions the array has. So that it looks more compact than Oscars way? Or it takes a few lines less code?
|
|
Oscar Giner
Member #2,207
April 2002
|
It's different, in the sense that the "typedefed" array must have a constant size. Accessing it should be faster, since it should have one less indirection (in case of 2d: instead of creating an array of pointers each one pointing to a row, you create a big table in memory with all data contiguous so accessing it is similar to a static 2d array). -- |
|
OnlineCop
Member #7,919
October 2006
|
Would it not be simpler (both in complexity and in understanding what is doing what) if you just used a struct? typedef struct 3d{ double x,y,z; } 3d; I don't see in what way you'll ever be using a 3D array like what you're suggesting: Every single point (5000*5000*5000) will have a single double in it: not a 3D coordinate; just a single floating-point value. This won't really be useful to you. If you're trying to conceptualize something in 3-space, and you have 5000 points scattered around that space, you want 5000*3 to mark each particle's coordinates. What you WANT is a coordinate for each particle (be it a point, a polygon, or even a sprite), and you can get 5000 of those easily (particle pumps). -- |
|
verthex
Member #11,340
September 2009
|
OnlineCop said: I don't see in what way you'll ever be using a 3D array like what you're suggesting: Every single point (5000*5000*5000) will have a single double in it: not a 3D coordinate; just a single floating-point value. Oh the example he gave on the link I used had 5000. I just need something like 5 really. It could be used for Ising modelling, maybe thats what he needed it for or the dimer problem. Oscar Giner said: Accessing it should be faster, Accessing your code or the typedef code?
|
|
Edgar Reynaldo
Member #8,592
May 2007
|
Use a simple class, a one dimensional array, and an accessor function to take care of finding the right index for a given z,y,x triplet. 1class ThreeDArray {
2private :
3 int d;// depth
4 int h;// height
5 int w;// width
6 double* array;
7public :
8 ThreeDArray() : d(0) , h(0) , w(0) , array(0) {}
9 ~ThreeDArray() {Free();}
10 void Resize(int depth , int width , int height) {
11 Free();
12 array = new double[depth*width*height];
13 }
14
15 double& Get(int z , int y , int x) {
16 return array[z*w*h + y*w + x];
17 }
18};
C/C++ Reference -|- cplusplus.com - The C++ Resources Network -|- SGI's STL guide |
|
verthex
Member #11,340
September 2009
|
Its nice Edgar, been looking for one of those except I always wondered if hashing the coordinates using multiplication takes longer than just using a standard access of? int array[depth][width][height];
|
|
Edgar Reynaldo
Member #8,592
May 2007
|
Well, it's {3 MULT, 2 ADD, 1 ACCESS} vs. {3 ACCESS}. The second way is probably somewhat faster, but then you have to deal with dereferencing three arrays, and they aren't stored sequentially like the first version would be. You'd have to profile it to see. C/C++ Reference -|- cplusplus.com - The C++ Resources Network -|- SGI's STL guide |
|
verthex
Member #11,340
September 2009
|
Edgar Reynaldo said: but then you have to deal with dereferencing three arrays, How exactly does c++ create a multidimensional array, what type of data structure is it? If you could give a link that would be fine. I already know from some testing that accessing a std::vector array is slower than a regular one.
|
|
Edgar Reynaldo
Member #8,592
May 2007
|
Well, there is a difference between a 3D compile time array, and a 3D run time array that you manually allocate as an array of arrays of arrays. The compile time array will be faster, but it's size has to be determined at compile time. Google / profile FTW. C/C++ Reference -|- cplusplus.com - The C++ Resources Network -|- SGI's STL guide |
|
verthex
Member #11,340
September 2009
|
Edgar Reynaldo said: Google / profile FTW.
|
|
Edgar Reynaldo
Member #8,592
May 2007
|
No, I meant 'Google' or 'Profile' For The Win. Not Google 'profile ftw'. C/C++ Reference -|- cplusplus.com - The C++ Resources Network -|- SGI's STL guide |
|
kdevil
Member #1,075
March 2001
|
As an alternative, look into boost::multi_array. To create a 3D array of, say, 5000x5000x10, you can do: #include <boost/multi_array.hpp> boost::multi_array<int, 3> some_array (boost::extents[5000][5000][10]); and then assign/retrieve values the way you'd expect: int values = 0; for (int i = 0; i < 5000; i++) for (int j = 0; j < 5000; j++) for (int k = 0; k < 10; k++) some_array[i][j][k] = values++; int my_value = some_array[1][2][3];
----- |
|
verthex
Member #11,340
September 2009
|
kdevil said: As an alternative, look into boost::multi_array. For some reason I'm tempted to ask if its better than std::vector?
|
|
kdevil
Member #1,075
March 2001
|
Neither is really "better": boost::multi_array and std::vector are designed to solve different problems (easy multidimensional arrays, and easy re-sizable arrays). If you're asking which is faster, I haven't done any tests, but Edit: Scratch that. They might be the same for a 1D array, but I'm positive that a 3-dimensional multi_array will be significantly faster than its vector equivalent (a vector of vectors of vectors). ----- |
|
verthex
Member #11,340
September 2009
|
I dissassembled the following code in codeblocks with GDB 7.2: int main() { int array[10]; //array[1] = 0; //int value = array[1]; //return 0; }
00401318 push %ebp 00401319 mov %esp,%ebp 0040131B and $0xfffffff0,%esp 0040131E sub $0x30,%esp 00401321 call 0x401720 <__main> 00401326 mov $0x0,%eax 0040132B leave 0040132C ret Does the line: call 0x401720 <__main> relate to, int main() or the exit of main? Notice I have no return and yet it has it. Is this the way its looked up BTW? array[z*w*h + y*w + x]; like Edgar had it?
|
|
OnlineCop
Member #7,919
October 2006
|
__main is name-mangled (munged) and there is actually another entry point. This basically calls the "real" main() function after allocating 0x30 bytes (48 bytes) on the stack. Since you declared main() to return an int, but neglected to include it, the compiler in this case returned 0. That functionality can vary by compiler. -- |
|
Arthur Kalliokoski
Member #5,540
February 2005
|
OnlineCop said: That functionality can vary by compiler. I thought C++ was supposed to do that by design. I really admire the U.S. Constitution. It's so much better than what we have now. |
|
|
1
2
|