Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Trouble passing arrays between functions. 4

Status
Not open for further replies.

mrhegemon

Programmer
Jul 3, 2003
20
US
I have written a function to calculate the n-degree polynomial fit of a given data set. I made the function in an external file and linked it to another program with a header file. I want it to do something like this, where a is an array for holding the polynomial coefficients:

[tt]//main program pseudo-code:

int main(...)
{
...
double* a;
a=polyfit(x,y,order,n);
...
}

//function pseudo-code (in another file):

double* polyfit(double* x,double* y,long order,long n)
{
...
...
return a;
}[/tt]

Unfortunately, this never compiles, always giving errors about passing a local variable address. I was able to get around it temporarily by defining the array in my main program and passing it as a parameter to be filled in the polyfit function. However, I would like to do it the manner I mentioned above. Any help is much appreciated.
 
the problem is that "a" is local to your main()...

solution...
1) (poor) :(
//global var
double* a;
int main(...)
{
...
a=polyfit(x,y,order,n);
...
}

2) (much better) dont return a, anyway a=polyfit(....);
double* polyfit(double* x,double* y,long order,long n)
{
return (dosomething); //where do something is your
//computation
}

jb
 
The calculation has an array of coefficients as it's result. I would like to return a reference to that array, as I understand that return cannot actually return arrays, blah blah blah about pointers and stuff. I just want to be able to assign the array created in my polyfit function to the array in my main function without having to pass an already allocated array to the polyfit function, have it changed there, and then just use the changes in my main function. I KNOW that way works, I've already compiled it, but I wanted to know if the way I said was possible/faster.
 
You need to allocate memory for a inside polyfit:

double* polyfit(double* x,double* y,long order,long n)
{
double *a = malloc(sizeof *a);
...
...
return a;
}
 
I did allocate memory for a in polyfit, I just thought that could be assumed from my pseudo-code.

Don't get confused because I used a in both functions. It is a local variable.

I want to create an array in an external function and return the pointer of that array so that I don't need to be defining the array in the function that is doing the calling. I want to define a pointer and assign it the value returned by the function I called, so I effectively have the array returned to me.

Did anyone see that in my pseudo-code?

Sorry to be so crabby, but all I want to know is whether it is possible or not. If possible, please tell me how.
 
> I was able to get around it temporarily by defining the array in my main program
> and passing it as a parameter to be filled in the polyfit function.
This is probably the best answer in the long run - it's certainly the most flexible way of tackling the problem. It removes from the called function all the problems of how to allocate the memory (stack, heap, whatever), and what to do with that memory once its finished with.

However, specific cases do warrant different approaches...

Dynamic allocation
Code:
double* polyfit(double* x,double* y,long order,long n)
{
  double *a = malloc( (sizeof *a) * n);  // synthesise double a[n];
  ...
  ...
  return a;
}
The problem with this is that main() now has to call free() at some point. This may or may not be a problem to you.

Static allocation
Code:
double* polyfit(double* x,double* y,long order,long n)
{
  static double a[SIZE];
  ...
  ...
  return a;
}
There are two main problems with this approach
1. you have to choose SIZE at compile time
2. You can't call the function twice and maintain two sets of results, in this manner
Code:
a=polyfit(x,y,order,n);
// you must finish using a before calling the function again
b=polyfit(x,y,order,n);
There is only one array inside the function. 'a' and 'b' will point to the same array.
 
Wait, so, you are saying that if I malloc() the memory inside the function, I can then pass the pointer with no problem, and all I have to worry about is cleaning up with a free()?

The reason I am making such a big deal is that the polyfit function returns array a with number of elements order+1. This is why I don't want to go through the trouble of calculating and allocating the memory outside of the function. It would be nice and easy to define a pointer, call the polyfit function and assign the array pointer it returns to the pointer I defined, and then destroy it with a free() when I am done with it.

Is that possible?
 
Of course.
Code:
double *retdoubleArr(int n) {
double *myarr = malloc(n * sizeof(double));
        if (myarr) {return myarr; }
        return NULL;
}

int main(void) {
/* stuff*/
double *mydouble;

        mydouble = retdoubleArr(number);
        /* do something */
        free(mydouble);
return 0;
}

There seems to be a trend here now that dynamic allocation
is evil. Get used to it folks. It's there for a reason and
calling free() is only a "problem" if your design is
bad in the first place.
 
> Wait, so, you are saying that if I malloc() the memory inside the function,
> I can then pass the pointer with no problem, and all I have to worry about is cleaning up with a free()?
Yes - you can call malloc() wherever you want, and call free() at any later point in the program when you're done with that block of memory.
 
Absolutely! Please don't misconstrue anything I've written elsewhere in this forum as meaning dynamic allocation is bad. No, it's wonderful, very useful, very necessary. Functions that allocate and don't free aren't automatically bad either; the worst I can say of them is that in unskilled hands of later programmers who don't understand the function, they present a risk of creating memory leaks, but that's the fault of the later programmer, in a sense.
 
General advises.
If you have function which allocate memory create another one to free it, like this:

double* getpolyfit(double* x,double* y,long order,long n)
void freepolyfit(double *a);

And always check pointer to NULL before calling free.
Better write own myFree(void *p); function which will check pointer to NULL before freeing it, and ALWAYS initialize ALL pointer to NULL in declaration, like in your case:
double *a = NULL;

if you are writing some general use library and going to use it for a long time with possible modification, try to use void pointer as return value and get functions for specific data access, like this:

void * createpolyfit(double* x,double* y,long order,long n);
double getpolyfitnode (void * pl);
....
void freepolyfit(void *pl);

That can be overkill in your case, but if your return something more compilcated that just one array, for example structure or array of stractures it can be very usefull, In this case end user will not depend on internal implementation: specific structure fields, type of memory allocator use (you may use different allocators than malloc/free or implement your own dynamic allocator on top of malloc). He will work with your pointer to the object as with black box only using API to access real data.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top