newbie troubles - creating an array dynamically. best practices.

  • Thread starter Anton Ishmurzin
  • Start date
A

Anton Ishmurzin

Greetings,

I would like to know, what's the right way of creating/initialising dynamic
array (which is multidimensional, generally speaking).

So I have some data represented by a matrix. dimensions, as well as values,
are determined at runtime. In order to hide the initialization of the
dynamic array, I wrote a function, that has to do the job.

It does it, but I am a bit concerned about it's correctedness.

That's the program. Questions will follow.
----CUT-HERE----
// program start here
#include <iostream>
#define N 10

// let's assume that I get this N from somewhere else, say
// from the user input, but I put it here like a macro for the sake of
// clarity. It explains dynamic memory allocation I perform below.

using namespace std;

double ** initialize_c();

int main()
{
double ** c;


c = initialize_c(); // A

for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
cout << c[j] << " ";
cout << endl;
};

return 0;
};

double ** initialize_c()
{
double ** c;

c = new double * [N];

for (int i = 0; i < N; i++)
c = new double[N];

for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
c[j] = 1.0;
return c;
};
----CUT-HERE----

So here are the questions:

if I repeat the line A (for instance, put it into a loop), creates it a new
pointer c in each loop entry?

Because as far as I understand, two lines with 'new' within the
initialize_c() allocate new memory for the array.

If the answer to the first question is "yes", then how'd i change the code
in order to make it initialize the pointer c at one and the same address
always?

How to free memory after such an initialisation?

Should I put a "static" specifier when I declare "double ** c" in
initialize_c()?

What are the best practices to initialize a multidimensional dynamic array?

Best regards,
Anton.
 
J

John Harrison

Anton Ishmurzin said:
Greetings,

I would like to know, what's the right way of creating/initialising dynamic
array (which is multidimensional, generally speaking).

So I have some data represented by a matrix. dimensions, as well as values,
are determined at runtime. In order to hide the initialization of the
dynamic array, I wrote a function, that has to do the job.

It does it, but I am a bit concerned about it's correctedness.

That's the program. Questions will follow.
----CUT-HERE----
// program start here
#include <iostream>
#define N 10

// let's assume that I get this N from somewhere else, say
// from the user input, but I put it here like a macro for the sake of
// clarity. It explains dynamic memory allocation I perform below.

using namespace std;

double ** initialize_c();

int main()
{
double ** c;


c = initialize_c(); // A

That is a really bad name for your function. Look at this example

double** d = initialize_c(); // oops, d is not c
initialize_c(); // oops, nothing being initialised at all

See why the function is badly named? Your function does not initialise
anything, it is how you use it that initialises something.

I wouldn't normally pick up on something like that, but the rest of your
post indicates that you have some serious confusion between allocation and
initialisation.

A better name for this function would be allocate_2d_array (for instance).
Code is some much easier to understand when you give things the right names.
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
cout << c[j] << " ";
cout << endl;
};

return 0;
};

double ** initialize_c()
{
double ** c;

c = new double * [N];

for (int i = 0; i < N; i++)
c = new double[N];

for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
c[j] = 1.0;


You can combine the above two loops

for (int i = 0; i < N; i++)
{
c = new double[N];
for (int j = 0; j < N; j++)
c[j] = 1.0;
}
return c;
};
----CUT-HERE----

So here are the questions:

if I repeat the line A (for instance, put it into a loop), creates it a new
pointer c in each loop entry?

It would allocate new memory, no pointers are being created in line A. You
create pointers like this

double ** c; // c is a new pointer
Because as far as I understand, two lines with 'new' within the
initialize_c() allocate new memory for the array.
Correct.


If the answer to the first question is "yes", then how'd i change the code
in order to make it initialize the pointer c at one and the same address
always?

There's some serious confusion here, unfortunately I can't figure out what
it is.

If you initialise pointer c, and then never assign to it again it will
always pointer at the same memory. If you initialise pointer c, but then
assign a different address to it, it will end up pointing somewhere else.
How could it be any other way?

If you don't want pointer c to point somewhere else, don't assign a new
address to it.
How to free memory after such an initialisation?

Should I put a "static" specifier when I declare "double ** c" in
initialize_c()?

That would have no effect at all. So whatever it is you are after its not
going to do it.
What are the best practices to initialize a multidimensional dynamic array?

Best regards,
Anton.

I think you need to try and explain yourself a bit better. Post again.

john
 
E

Evan Carew

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Anton,

Looking at your code, I see you chose to use C arrays to construct a
multi-dimensional array of doubles. While this is a perfectly acceptable
method (ignoring your specific implementation), this method doesn't
integrate well with C++'s Standard Template Library.

In the past, when I was starting out with C++, I have used the brain
dead method of a vector of vectors, e.g.:
vector< vector<double> >
While this works, the interface is somewhat ugly & the overhead can be
unacceptable. To fix this, the authors of the Boost library, provide
several solutions for the mathmatically inclined which address
efficiency & usability. Specifically, the MultiArray library (
http://boost.org/libs/multi_array/doc/user.html ) allows the user to
create a multidimensional array & initialize it just as you would any
other automatic variable. This means that the array, and all its
associated memory is cleaned up after the enclosing code block is left.
Optionally, this functionality can be altered so the multiarray doesn't
delete the memory it refferences.

Hope this helps,
Evan

P.S.
Code example of use of multi array follows:
// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);

// Assign values to the elements
int values = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
A[j][k] = values++;



Anton said:
Greetings,

I would like to know, what's the right way of creating/initialising
dynamic array (which is multidimensional, generally speaking).

So I have some data represented by a matrix. dimensions, as well as
values, are determined at runtime. In order to hide the initialization
of the dynamic array, I wrote a function, that has to do the job.

It does it, but I am a bit concerned about it's correctedness.

That's the program. Questions will follow.
----CUT-HERE----
// program start here
#include <iostream>
#define N 10

// let's assume that I get this N from somewhere else, say
// from the user input, but I put it here like a macro for the sake of
// clarity. It explains dynamic memory allocation I perform below.

using namespace std;

double ** initialize_c();

int main()
{
double ** c;


c = initialize_c(); // A

for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
cout << c[j] << " ";
cout << endl;
};

return 0;
};

double ** initialize_c()
{
double ** c;

c = new double * [N];

for (int i = 0; i < N; i++)
c = new double[N];

for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
c[j] = 1.0;
return c;
};
----CUT-HERE----


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFAcaOCoo/Prlj9GScRAqlKAJsEvo5IWnMTWqUxZML1MIkSQQ1DnwCfTaUE
cfRph/m4gOWatIRVKvorGEM=
=LJFC
-----END PGP SIGNATURE-----
 
A

Anton Ishmurzin

Greetings,

I'd like to thank everybody participated in the discussion. Thanks for the
links. I really lack of knowledge, and this faq is exactly what I was
missing. Once again, thanks.

Anton.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top