-3

I have a variable int*** dp, and I want to pass it to a function by reference to initalize it. But when I try to call the function:

int*** dp;
int c1, c2, c3;
void initialize(int*** d)
{
    d = new int**[c1 + 1];
    for(int i = 0; i <= c1; i++)
    {
        d[i] = new int*[c2 + 1];
        for(int j = 0; j <= c2; j++)
        {
            d[i][j] = new int[c3 + 1];
            for(int k = 0; k <= c3; k++)
            {
                d[i][j][k] = 0;
            }
        }
    }
    d[0][0][0] = 1;
}

initialize(dp);

I get the following compile error: invalid conversion from 'int' to 'int***' [-fpermissive].

Even if I try to pass it by reference:

void initialize(int*** &d)

It still doesn't work! Can you explain me why it doesn't work and how I can fix it?

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • 3
    For me any `type***` is failure of encapsulating matrix in a class. It is noneffective way to emulate matrix. `std::vector>>` would be better, but still sucks. – Marek R Jan 07 '21 at 17:08
  • 11
    Don't be a [three star programmer](https://wiki.c2.com/?ThreeStarProgrammer), especially in C++. – Kevin Jan 07 '21 at 17:13
  • What compiler are you using? The `initialize(int***&d)` variant, while really _really_ bad style (do **not** put this in production), works for GNU C++ 8.3.0. – digitalarbeiter Jan 07 '21 at 17:13
  • 2
    Which line is giving that error. None of the lines in the code you pasted should give that error? – Mike Vine Jan 07 '21 at 17:20
  • This is not C++. – Enlico Jan 07 '21 at 17:24
  • @Enlico What makes you think it's not C++? – Kevin Jan 07 '21 at 17:25
  • 2
    You can't put function calls in the middle of nowhere, please show a [mre]. – Lukas-T Jan 07 '21 at 17:38
  • @Kevin, 1. your first comment, 2. the fact that there's not much more than `new` instead of `malloc` to make this code be C++ instead of C. – Enlico Jan 07 '21 at 17:52
  • @Enlico So it's C because it doesn't contain "enough" `new`? The fact that it contains `new` at all means, that it can't be C. But I guess you wanted to imply that this code uses mostly coding practices from C that you wouldn't use in (modern) C++? Which is true. Sadly that's how C++ is taught in many places. – Lukas-T Jan 07 '21 at 18:26
  • @churill, you got my point and your guess is right. This is "not" C++ just like `for f in $(ls *.mp3)` is "not" `bash`, and so on. And yes, that's so sad. – Enlico Jan 07 '21 at 18:31

1 Answers1

2

This question is a bit difficult to answer, because there are two more fundamental problems on top of it:

  1. knowledge of the C++ standard library and the C++ way of handling matrices, and
  2. understanding how a function like this should be structured in general.

For the first issue (how to matrix in C++) see https://www.boost.org/doc/libs/1_75_0/libs/numeric/ublas/doc/matrix.html (Boost does some pretty hardcode stuff, so be prepared.)

I shall focus on the second issue.

A function that allocates a resource (like here a couple of int) should return that resource, not manipulate its parameter. Likewise, the parameters that describe the resource (in your case, the dimensions) should be parameters. So your function becomes:

int*** new_matrix(int c1, int c2, int c3) {
    int*** d = new int**[c1];
    for(int i = 0; i < c1; i++)
    {
        d[i] = new int*[c2];
        for(int j = 0; j < c2; j++)
        {
            d[i][j] = new int[c3];
            for(int k = 0; k < c3; k++)
            {
                d[i][j][k] = 0;
            }
        }
    }
    d[0][0][0] = 1;
    return d;
}

Invoking it returns the new matrix:

int*** dp = new_matrix(1, 2, 3);

One more thing: in C/C++ you don't do this c1+1 business. A vector v of c1=2 has two elements, v[0] and v[1]. No monkeying about with v=new int[c1+1]; v[2]=0;. In C/C++ it is not done. Here's why: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html

digitalarbeiter
  • 2,295
  • 14
  • 16
  • @Kevin is right, of course, don't be a Three Star Programmer, but I assume you're doing this for learning/as an assignment, so I run with it. For production, just use boost's matrix class. It's faster, more powerful, and actually works. – digitalarbeiter Jan 07 '21 at 17:51