How to create (initialize) a double pointer ??

Hi Guys,

I know programming in general but I am kind new to C++ pointer concept.
I got this project at school and I have no idea how to start...
So please give me some hints if you can,

Here is my case:

- I have many mechanical parts in 3D drawing (exact number of parts is not known as # of parts varies from drawing to drawing)
ex: I have parts a, b, c in drawing 1
parts d, e, f, g, h in drawing 2

- each part has its own array of doubles to store its position in space relative to other parts in the 3D drawing.
ex:part a has an array of double a_pos[12] relative to the absolute point in the drawing,part b has an array of double b_pos[12] but relative to part a, c with c_pos[12] relative to part b.

- I need to perform some recursive sum in order to determine the absolute position of each part in the 3D drawing by summing the arrays of relative position. And loop my code through all the drawings that I have.

Now, since the number of parts in a drawing is unknown, I think I might need my first pointer (double *ptr) to point to a dynamic list, then my second pointer (double **ptr) to point to the relative position arrays (double a_pos[12], b_pos[12], c_pos[12],...etc)

I think this is what I need to do, yet I have no idea how to declare a double pointer as well as dynamic size of list...

Can someone please teach me how and direct me to the right direction?

Thanks so much,

Howie
2D arrays are more trouble than they're worth, most of the time. You'd need to allocate a double**, then allocate 12 double*s for each part. This requires 1+#ofparts allocations. Cleanup is just as bad, as you have to delete each double* then delete the overall double**.

The way to do this is:

1
2
3
4
5
6
7
8
9
10
11
12
double** buf2d;
buf2d = new double*[number_of_parts];
for(i = 0; i < number_of_parts; ++i)
  buf2d[i] = new double[12];

// to get point 5 in part C:
buf2d[2][5];

// cleanup is equally ugly:
for(i = 0; i < number_of_parts; ++i)
  delete[] buf2d[i];
delete[] buf2d;


this also requires a double indirection which means more overhead.

There are two other solutions you may want to consider. One is to allocate 12*parts doubles, and use some basic math to index them:

1
2
3
4
5
6
double* buf = new double[number_of_parts * 12];

// point 5 in part C:
buf[ (2*12) + 5 ];

delete[] buf;


Or... if you want to avoid potentially erroneous math, drop your points in a struct:
1
2
3
4
5
6
7
8
9
10
11
struct part
{
  double pts[12];
};

part* buf = new part[number_of_parts];

//point 5 in part C
buf[2].pts[5];

delete[] buf;


I recommend the 3rd option. It's the easiest and will require no changes if you want to add additional information to the parts (more points, or anything else)
Last edited on
You can use vectors which do the clean up automatically
http://www.cplusplus.com/forum/articles/7459/
Hey guys,

Thanks so much for replying my message so fast!! :)
I have an idea of how to initialize a 2D array now.

Two addition questions:

1- In the first solution proposed by Disch,
1
2
3
4
5
6
7
8
9
10
11
12
double** buf2d;
buf2d = new double*[number_of_parts];
for(i = 0; i < number_of_parts; ++i)
  buf2d[i] = new double[12];

// to get point 5 in part C:
buf2d[2][5];

// cleanup is equally ugly:
for(i = 0; i < number_of_parts; ++i)
  delete[] buf2d[i];
delete[] buf2d;


After deleting all the memory location pointed by the pointers, do I need to assign manually each pointer back to NULL in order to prevent memory leaks (dangling pointers)? Or, delete[] is suppose to fixed this problem already?

2- Is there a way to dynamically increase the size of my 2D array?

Ex: After going through my Drawing #1, I created an array of size 107x12. However, since I am looping through all the drawings I have, the second drawing returns an additional 105 parts.

Is there any way I can simply append those 105 parts into the original 2D array to make it [ (107+105)x12]? or I have to create a separate list of size 212x 12 then copy the first 107 rows of the old array into the new array? Or, is there any better way of doing it?

Thanks so much!! You guys saved my day!! :)

Howie
1. delete frees the memory so you don't need to set the pointers to 0 (Just know that they point to a memory no longer owned by your program so you would have to reassign them before using again)

2. You have do copy the array in a bigger one if using pointers. vectors do that automatically
edit: whoops -- the wrong thing got pasted in here before XD


You do not have to set them to NULL. But delete doesn't do it either. NULL pointers aren't the same thing as freed pointers.


2- Is there a way to dynamically increase the size of my 2D array?


Not easily. You'd have to allocate a new one and copy all the old information over. If you want to do this then Bazzy's suggestion of using vector is what you definatley want to do (vector is a dynamically resizable array). It takes care of all of that for you

1
2
3
4
5
6
7
8
9
10
struct part
{
  double points[12];
};

vector<part> myparts;

myparts.resize(number_of_parts);
myparts[2].points[5] = 3.1415;
//etc 


Is there any way I can simply append those 105 parts into the original 2D array to make it [ (107+105)x12]? or I have to create a separate list of size 212x 12 then copy the first 107 rows of the old array into the new array? Or, is there any better way of doing it?


A better way would to create a seperate array for the new image's parts and store all of these arrays in another container (another vector is fine if you need random access). Although this gets a little weirder, because storing exceedingly large things in a vector (like a vector with 100+ elements) is very inefficient because vectors may need to copy all the data over when it needs to be resized. So instead, store a pointer to the vector in the other vector. But then cleanup isn't automatic.

I worded that poorly, so here's an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
typedef std::vector<part>   drawing;

vector<drawing*> mydrawings;

// to add a new drawing
drawing* d = new drawing;
d->resize(number_of_points);

mydrawings.push_back(d);

// to get point 5 of part 4 of drawing 3:
mydrawings[3]->at(4).points[5];

// to cleanup
while(!mydrawings.empty())
{
  delete mydrawings.back();
  mydrawings.pop_back();
}


It might be best to encapsulate all of this inside a DrawingSeries class or something, then you can make your own functions to get the information you need in the way which is easiest to work with.
Last edited on
Topic archived. No new replies allowed.