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? :-)

Swaroop
1,3094 gold badges19 silver badges34 bronze badges
asked Aug 24, 2010 at 7:14
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".

Alberto Chiusole
2,8842 gold badges19 silver badges28 bronze badges
answered Aug 24, 2010 at 7:19
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.

answered Aug 24, 2010 at 7:26

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.

answered Aug 24, 2010 at 8:13

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.

answered Aug 24, 2010 at 7:19

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.

answered Aug 24, 2010 at 7:17

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;
}
answered Jan 13, 2013 at 0:13

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

answered Aug 9, 2021 at 13:29

1 Comment

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

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.