9

in C++ I want to initialize a double matrix (2-dimensional double array) like I would normally do without pointers like so:

    double data[4][4] = {
    1,0,0,0,
    0,1,0,0,
    0,0,1,0,
    0,0,0,1
};

However, since I want to return and pass it to functions, I need it as a double** pointer. So, basically I need to initialize data in a nice way (as above), but then afterwards I need to save the pointer to the 2D-array without losing the data when the function exits.

Any help on this? :-)

5
  • 4
    Why do you need it as a double** ? What's wrong with a double (*)[4] ? Commented Aug 24, 2010 at 7:16
  • This is C++. Can this be a class, with this array as a member, which passes a reference back when you call a member function? Commented Aug 24, 2010 at 7:23
  • possible duplicate of Passing two-dimensional array via pointer It's C, not C++, but it's exactly the same issue. Commented Aug 24, 2010 at 7:28
  • None of the answers have hit bulls eye. I found out I can do this: double ** d = new double[4][4]; But, how will I initialize the value without the chore of writing code like: d[0][0] = 1; d[0][1] = 0;... Commented Aug 24, 2010 at 8:24
  • No, you can't. For example, g++ refuses to compile your snippet: error: cannot convert 'double (*)[4]' to 'double**' in initialization. Commented Aug 24, 2010 at 13:58

7 Answers 7

10

Unless you are particular about pointers, I would prefer a reference here

void init( double (&r)[4][4]){
    // do assignment
    r[0][0] = 1;
}

int main(){
    double data[4][4] = {
        1,0,0,0,
        0,1,0,0,
        0,0,1,0,
        0,0,0,1
    };

    init(data);
}

By the way, if you pass it to a function in this manner, you would be "assigning" rather than "initializing".

Sign up to request clarification or add additional context in comments.

2 Comments

I think this answer is getting warmer. It might be the one I'm looking for!
By replacing "init" with a copy function, this models my problem elegantly. Thanks!
6

Are all your matrices 4x4? Then I would simply define a class with a double[4][4] member and pass objects of that class around:

class Matrix
{
    double m[4][4];
    // ...
};

void function(const Matrix& matrix)
{
    // ...
}

If you need matrices of various dimensions, but they are known at compile time, use a template:

template <size_t n>
class Matrix
{
    double m[n][n];
    // ...
};

template <size_t n>
void function(const Matrix<n,n>& matrix)
{
    // ...
}

This saves you from dealing with array-to-pointer decay and makes the code more readable IMHO.

Comments

6

First, declaration of the double dimensional array is not correct. It needs to be done as follows:

double data[4][4] = {  
        {1.0,0,0,0},  
        {0,1,0,0},  
        {0,0,1,0},  
        {0,0,0,1}  
    };

Second, for passing it in a function you can do it like

show(data);

In the function declaration, you need to give the argument as an array with giving all dimensions except the first. So the declaration would look like:

void show(double arr[][4])
{
   ...
   ...
}

This passes the array as a reference wihout you needing to use a pointer.

Hope this helped.

1 Comment

Thanks! That one-line initialization was what I had been looking for.
3

double (*)[4] is very different from double **

Just sketch the layout of your doubles in the memory for both and you should understand why you can't use them interchangeably.

1 Comment

since I don't know or understand "double (*)[4]", I can't sketch it. What does it mean?
1

Initialize temporary variable in this way and then copy it to the dynamically allocated memory.

Comments

1

How about this (with pointers, and does what you asked for)

#include <iostream>

using namespace std;

int refer(double (*a)[4])
{
   cout<<"First value is "<<(*a)[0];
   (*a)[0] = 37;
   cout<<"changed value is "<<(*a)[0];
}

int main()
{
   double data[4][4] = {
    1.0,0,0,
    0,1,0,0,
    0,0,1,0,
    0,0,0,1
   };
   refer(data);
   return 0;
}

Comments

0

late to the party, but.... c++ is meant to work with c++ stl. (At least according to Bjarne Stroustrup if you're using raw pointers in c++ then you're doing something wrong.)

#include <array> // on top
// ..    

std::array<std::array<int, 4>, 4> data {{
    {1,0,0,0},
    {0,1,0,0},
    {0,0,1,0},
    {0,0,0,1}
}};

// access it normally 

data[1][2] = 123;
std::cout << data[0][0]; // prints 1. (#include <iostream>)

// You can return std::array from a function as a normal return value, don't worry it is not going to be reallocated, or missing.

std::array<std::array<int, 4>, 4> give_me_data() {
  std::array<std::array<int, 4>, 4> data {{
    {1,0,0,0},
    {0,1,0,0},
    {0,0,1,0},
    {0,0,0,1}
  }};
  return data;
}

(works with Mac's XCode, also gcc supports it https://stackoverflow.com/a/12616826/1031191)

What's the benetif? It works nicely with std algorithms, knows its size, same performance, etc. ref: std::array vs array performance

1 Comment

Also, if you don't know the size, use std::vector.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.