-1

I am trying to change the value of ydot[] in func() so that I can use it in my ode() function. However, it seems like I do not have access to ydot[] anymore after I called func(). I am passing func() into ode() as a function pointer called dydt. Here are my two functions:

    void func(double t, double y[], double ydot[])
    {
        for(int i = 0; i < 18; i++){
            ydot[i] = y[i]+1;
        }
    }

    typedef void (*dydt_func)(double t, double y[ ], double ydot[ ]);

    void ode(double y0[ ], double yend[ ], int len, double t0,
             double t1, dydt_func dydt)
    {
        double ydot[len];

        dydt = &func;

        //This prints out all the value of ydot[] just fine
        for (int i = 0; i < 18; i++){
            cout << ydot[i] << ",";
        }

        dydt(t1, y0, ydot);

        //This SHOULD print all the revised value of ydot[]
        //But I get an error instead:
        //Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

        for (int i = 0; i < 18; i++){
            cout << ydot[i] << ",";
        }
    };

I have access to ydot[] just fine before I called dydt(). Is there something wrong with the way I use function pointer? Or should I pass a pointer of ydot[] or something to func() instead? Thank you guys for helping!

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
cxc
  • 201
  • 2
  • 10
  • 1
    Since C++ doesn't have [variable-length arrays](https://en.wikipedia.org/wiki/Variable-length_array) your code is technically invalid. – Some programmer dude Sep 22 '18 at 20:01
  • As for your problem, please learn how to use your debugger to catch the crash in action, and locate when and where in your code it happens. – Some programmer dude Sep 22 '18 at 20:03
  • @Someprogrammerdude It says EXC_BAD_ACCESS when I get to the second for loop trying to print out ydot[i]. But how can I print it out successfully before I called dydt()? – cxc Sep 22 '18 at 20:06
  • 2
    By the way, will the actual sizes of the arrays you have be *at least* `18` elements? Will no one be smaller? How do you call the `ode` function? With what arguments? Can you please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) to show us? – Some programmer dude Sep 22 '18 at 20:07
  • What value does `len` have when you call `ode`? If it is less than 18 you've entered the realm of Undefined Behavior. – 1201ProgramAlarm Sep 22 '18 at 20:11
  • @1201ProgramAlarm I should've initialized the array with size of `len`, but I am not sure if I can have an array with variable-length... – cxc Sep 22 '18 at 20:13
  • @πάντα ῥεῖ I can print out the value of `ydot[]` inside `dydt()` as well. But the address of `ydot[]` became `0x0` as soon as `dydt()` is returned in `ode()` – cxc Sep 22 '18 at 20:16
  • @cxc As it was mentioned in the formerly marked [duplicate](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope), you cannot access any variables or memory addresses that were stack allocated inside a particular functions scope. – πάντα ῥεῖ Sep 22 '18 at 20:19
  • @πάνταῥεῖ Would it work if I allocate the memory inside `ode()` before it goes into the `dydt()` function? Would I still have access after I called `dydt()`? – cxc Sep 22 '18 at 20:21
  • Why are you assigning to `dydt` inside the `ode()` function? It's supposed to be a function parameter that the caller passes. – Barmar Sep 22 '18 at 20:23
  • @πάνταῥεῖ All I want is to change the value of `ydot[]` inside `dydt()`. Is there anyway I can achieve that? – cxc Sep 22 '18 at 20:26
  • Calling `func()` can't have any effect on the allocation of the `ydot` array. the only possible problem is accessing outside the array bounds, if `len < 18`. – Barmar Sep 22 '18 at 20:26
  • @Barmar That is what I think! But I could not even print out `ydot[0]` after calling `func()`. – cxc Sep 22 '18 at 20:29

1 Answers1

0

C++ doesn't have variable-length arrays like C does, so you need to use new to allocate the array with a variable size, or use a std::vector instead of an array.

You need to pass the size of the array to func, so that it can limit the number of elements it updates to that size. Your code will have undefined behavior if the array length is less than 18.

void func(double t, double y[], double ydot[], int len)
{
    for(int i = 0; i < len; i++){
        ydot[i] = y[i]+1;
    }
}

typedef void (*dydt_func)(double t, double y[ ], double ydot[ ], int len);

void ode(double y0[ ], double yend[ ], int len, double t0,
         double t1, dydt_func dydt)
{
    double *ydot = new double[len];

    dydt = &func;

    //This prints out all the value of ydot[] just fine
    for (int i = 0; i < 18; i++){
        cout << ydot[i] << ",";
    }

    dydt(t1, y0, ydot, len);

    for (int i = 0; i < len; i++){
        cout << ydot[i] << ",";
    }
};
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thank you very much! I think the problem is that I did not allocate memory for `ydot` in `ode()`. Thank you all for helping! – cxc Sep 22 '18 at 20:51
  • @cxc If your compiler allows the VLA extension, you allocated it with `double ydot[len];` – Barmar Sep 22 '18 at 20:54