0
#include <iostream>
using namespace std;

int getDegree()
{
    int degree;
    cout << "Enter degree of polynomial" << endl;

    cin >> degree;

    return degree;
}

int* getPoly(int degree)
{
    cout << "Enter coefficients in order of power of x. e.g. for 2 + x + 3x^2, enter 2 then 1     then 3" << endl;

    int coeff [degree +1];
    for (int i = 0; i <= degree; i++)
    {
        cin >> coeff[i];
    }

    return coeff;
}

int* polyder(int p[], int degree)
{
    int dp[degree];

    for(int i = 0; i < degree; i++)
    {
        dp[i] = p[i+1] * (i+1);
    }

    return dp;
}

int main(int argc, const char * argv[])
{
    int degree = getDegree();
    int p = *getPoly(degree);
    int dp = *polyder(&p, degree);

    for(int i = 0; i < degree +1; i++)
        cout << "   " << p[i] << " x^" << i;
    cout << endl;

    for(int i = 0; i < degree +1; i++)
        cout << "   " << dp[i] << " x^" << i;
    cout << endl;

    return 0;
}

I am getting an error during the print statements. I am not worried about the math involved, just how to pass the arrays between functions/methods.

Can anyone find why this is not working? I am new to C++, used to Java.

  • [undefined behaviour](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – chris Mar 11 '14 at 01:21

3 Answers3

2

Can anyone find why this is not working?

In C++ variables are destroyed when the scope in which they were declared ends. You return an address of a variable that doesn't exist when the function ends:

int* getPoly(int degree)
{
    int coeff [degree +1];
    // ...
    return coeff;
}

If you wish the variable still exists after the function ends, you have to allocate it using new:

int* getPoly(int degree)
{
    int *coeff = new int[degree +1];
    // ...
    return coeff;
}

And, at the end of your main function (or wherever you don't need the array anymore), call delete[] to deallocate the memory:

int *p = getPoly(degree);
delete[] p;

The Array name is essentially a pointer to the first element of the array (as you can see in the code above, I've declared p as a pointer to int), so you pass them to other functions just by providing their name:

int* polyder(int p[], int degree){/*do something here*/}
// <-- some other code
int *p = getPoly(degree);
int* returnedArray = polyder(p,degree);
Paweł Stawarz
  • 3,952
  • 2
  • 17
  • 26
  • That too. Big one that. – aruisdante Mar 11 '14 at 01:25
  • Of course, you shouldn't actually use `new` and `delete` yourself, unless you can't use existing resource-management classes for some reason. In this case, return `std::vector`. – Mike Seymour Mar 11 '14 at 01:48
  • 1
    And arrays aren't "essentially pointers"; they're convertible to pointers and, confusingly, can be declared using array syntax when they're function parameters. – Mike Seymour Mar 11 '14 at 01:51
  • "Arrays are essentially pointers" - no, they are completely different entities. Just because you can create a pointer to the first element of an array, does not mean the array IS that pointer. – M.M Mar 11 '14 at 02:55
  • @MikeSeymour and MattMcNabb of course you're right. I've edited that sentence to be more true, was too big of a shortcut there. – Paweł Stawarz Mar 11 '14 at 17:31
0

First of all, the line

int coeff [degree +1];

is not a valid C++ statement unless 'degree' is a constant, even through some compilers may allow it.

Even if some compiler allowed it, the space for coeff is allocated from the stack and will be invalid after the function returns. Hence, the line

return coeff;

returns an memory location that will be invalid at its usage.

In order to return valid memory function, replace the line

int coeff [degree +1];

by

int* coeff = new int[degree];

You don't need degree+1 items in the array.

Similar changes are needed in the function polyder.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
-1

The thing to remember about arrays in C++ is that unlike Java, they are not objects (at least in the way they are in Java). They're simply pointers to a block of allocated memory, and the [] operator simply automatically does the math to move the pointer to the correct location.

When passing arrays between functions, you're basically just passing a pointer. Unless you want to get into some highly complicated and likely too much for your use case code, you should always pass the size of the array along with it to ensure that your indexes always stay in bounds.

And as the other answer points out, you need to ensure that the life cycle of the array lasts as long as you need it to. Simply returning a pointer to an object doesn't keep it alive like returning a reference does in Java.

aruisdante
  • 8,875
  • 2
  • 30
  • 37
  • Arrays ARE blocks of allocated memory, they are not pointers to it. A pointer to an array or an array's elements is a different entity to an array, in exactly the same way that with `int x;`, `&x` is different to `x`. – M.M Mar 11 '14 at 02:56
  • The C++ terminology for "not Java-like objects" is to say that arrays are not rvalues, or that arrays do not have value semantics. – M.M Mar 11 '14 at 02:57
  • @MattMcNabb My point was that `value[]` is no different than `value *` with respect to passing to functions, and realistically `char value[size]` is simply syntactic sugar around `char * value` pointing to a stack-allocated block of `(size*size_of(char))`, unlike in Java where there is in actual object with information about it such as its size. – aruisdante Mar 11 '14 at 03:31
  • In first paragraph you said "They're simply pointers to a block of allocated memory" which is completely untrue, that's what I was responding to. `char value[size]` is only syntactic sugar in a function's formal parameter list; in all other contexts it is completely different to `char * value`. – M.M Mar 11 '14 at 03:55