-4

I have two functions as shown below:

1.

void calcoeff (double gamma, double delx, double A, double B, int n)
{
    int i;
    double halfdelx, sp = 0;
    double diag[n], upp[n-1], low[n-1], righ[n], X[n], sc[n];
    halfdelx = delx / 2;
    for (i = 1; i <= n; i++)
    {
        X[i] = i - 0.5;
        sc[i] = 8 * X[i];
        if (i == 1 || i == n)
        {
            diag[i] = ((gamma/delx) + (gamma/halfdelx) + sp);
        }
        else
            diag[i] = ((gamma/delx) + (gamma/delx) + sp);
        cout << "\ndiag" << i << "=" << diag[i] << "\n";
    }
    for (i = 1; i <= n-1; i++)
    {
        upp[i] = -1 * (gamma/delx);
        low[i] = -1 * (gamma/delx);
        cout << "\nupp" << i << "=" << upp[i] << setw(15) << "low" << i << "=" << low[i] << "\n";
    }
    for (i = 1; i <= n; i++)
    {
        if (i == 1){righ[i] = ((1/halfdelx) * A + sc[i]);}
        else if (i == n)
        {
            righ[i] = ((1/halfdelx) * B + sc[i]);
        }
        else
            righ[i] = sc[i];
        cout << "\nrigh" << i << "=" << righ[i] << "\n";
    }
    return;
}

2.

void TDMA (double diag[], double upp[], double low[], double righ[], int n)
{
    int i;
    double fact, phi[n];
    for (i = 2; i <= n; i++)
    {
        fact = low[i-1] / diag[i-1];
        diag[i] = diag[i] - fact * upp[i-1];
        righ[i] = righ[i] - fact * righ[i-1];
    }
    phi[n] = righ[n] / diag[n];
    for (i = n-1; i >= 1; i--)
    {
        phi[i] = (righ[i] - (upp[i] * phi[i+1])) / diag[i];
    }
    cout << "\nThe solution is as follows:\n";
    for (i = 1; i <= n; i++)
    {
        cout << "\nphi" << i << " = " << phi[i] << endl;
    }
    return;
}

The first function calculates and gives four arrays which has to be sent to second function as input parameters to get final phi array. So in the main function I have declared all the variables required by these two functions and I have called these two functions successively in the same order. The problem which I have noticed is that the first function is giving four arrays with correct values but the second function is not giving the correct result (as per the code). I have also noticed that the arrays given by first function are not going into second function as input parameters. The second function calculation is all based on the arrays given by first function. Can anyone help me in how to send the output of first function to second function? Thanks in advance.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • 1
    Use `std::array` and return the array by value - or use `std::vector` if you need dynamic arrays. – Ted Lyngmo Feb 18 '19 at 16:39
  • 2
    `diag` in `calcoeff` is a local variable, distinct from and unrelated to whatever variable you might have in `main`. You say the function "calculates and gives four arrays" - I see the calculating part, but not the giving part. – Igor Tandetnik Feb 18 '19 at 16:39
  • 3
    `double diag[n], upp[n-1], low[n-1], righ[n], X[n], sc[n];` is using VLA's which are not standard in C++. Compile using `-pedantic-errors` to stop it from compiling. Use `std::vector` to get it to compile afterwards. – NathanOliver Feb 18 '19 at 16:42
  • `if` in `for` loops that could be so easily be split... And `diag[n]` is accessed, full blown UB. – Matthieu Brucher Feb 18 '19 at 16:44
  • You do know that indices start at 0 in C++, right? – Matthieu Brucher Feb 18 '19 at 16:45

1 Answers1

0

It is not possible to return an array value (speaking of array types; not to be confused with std::array) from a function in C++.

It is however possible to return class instances, and class instances can contain arrays. There is a class template for wrapping an array into a class in the standard library: std::array. Note that the size of a member array must be a compile time constant (just like all array variables), so this approach doesn't work if the array needs to have a run time size.

Besides being limited to constant sizes, copying data structures around can be quite slow. A common approach is to let the caller of the function create the data structure, and pass an output iterator to an element of the structure - and possibly the number of elements or a second iterator to denote a range. In case of arrays, a pointer is often used. The function can use the provided iterator(s) to modify the data structure. An example:

const int n = 42;

void fill_arr(double*);
void use_arr(const double*);

int main() {
    double arr[n];   // an array is created in main
    fill_array(arr); // this function modifies the array
    use_arr(arr);    // the array can be passed to other functions
}

Since there can be many arguments, it is possible pass multiple iterator ranges to a single function.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Simply plain wrong. In C++, we use exclusively `std::array` and you can return it. Using raw array which exists only to be backwards compatible with old code isn't an excuse to declare "this is impossible". It also used to be impossible to prevent memory leaks when you get an exception right before you `delete[]` but that doesn't mean that it's impossible nowadays. `std::` is a thing, use it. – Purple Ice Feb 18 '19 at 16:57
  • @PurpleIce I'm not convinced you read the answer in it's entirety. The answer says that you cannot return an array by value from a function (which is true) and then introduces `std::array` as a returnable wrapper (which it seems is what you are saying the answer should be). – François Andrieux Feb 18 '19 at 17:01
  • 1
    @PurpleIce `std::array and you can return it` This does not contradict with my answer. `std::array` is not an array; it is a class template. As I've written in the answer, it is possible to return class instances, and explicitly mention that `std::array` exists. Returning objects that contain arrays has always been possible even before `std::array` was introduced. It doesn't change the fact that arrays cannot be returned in C++. – eerorika Feb 18 '19 at 17:05
  • Yes, you're right, we don't return arrays, we return pointers to them and that's all array identifier name is anyway. – Purple Ice Feb 18 '19 at 17:06
  • 2
    @PurpleIce Arrays and pointers are not the same. An array's identifier is not a pointer. Arrays *do* decay to pointers easily but they are **not** the same thing. Returning an array and returning a pointer to the first element are very different concerns. It is entirely correct to say that you can't return an array value in c++ (though the wording may lead to confusion if either party assumes the term refers to `std::array`, but this answer addresses that by introducing it later). – François Andrieux Feb 18 '19 at 17:09