Reputation: 1173
I have some C code that essentially looks something like
double* my_function(double* input) {
double* output = (double*) malloc(...);
// Do some stuff to output based on input
return output;
}
Assuming that I have already built an array called my_var_in, my main code has something like
double* my_var_out = my_function(my_var_in);
This creates new memory, which my_var_out points to; most of the time that's exactly what I want to happen. However, sometimes I just want to update the already existing memory. If I write
double* my_var = ... ; // allocate and fill my_var as desired
my_var = my_function(my_var);
Then I lose the pointer to the previously existing memory since my_var now points to the newly allocated memory. I've played around with several different ideas for how to get around this.
1) I know I can get this to work by changing the function style to something like
void my_function(double* destination, double* source) {
// Check if destination == source and update based on this
I've previously developed with this style of passing the destination pointer as an input argument and updating it there; it works great functionally, but I like the style of outputting pointers better and want to keep developing with it.
2) Based on here and here, it seems that the __builtin_return_address function could be of some use. I think I can use this function to compare the input address with the output address and allocate/update based on that. After reading the documentation here, I wrote the following test
int* just_testing(int* in) {
void* ptr = __builtin_return_address(0); // the return address of just_testing
printf("Input address: %p\n", in);
printf("From function: %p\n", ptr);
return in;
}
int main(int argc, char** argv) {
int* out = (int*) malloc(sizeof(int));
out[0] = 2;
printf("From main before call: %p\n", out);
out = just_testing(out);
printf("From main after call: %p\n", out);
return 0;
}
This gives me the output
From main before call: 0x19b2010
Input address: 0x19b2010
From function: 0x4011f1
From main after call: 0x19b2010
Unfortunately, the results from __builtin_return_address don't match the address of the variable that receives the return from the function, which I did not expect.
Why aren't the addresses the same? I also welcome any constructive suggestions on a different approach besides the two I've listed here.
Upvotes: 2
Views: 9260
Reputation: 41617
The cleanest solution is to have two separate functions:
#include <stdlib.h>
#include <string.h>
void compute_inplace(double *data) {
data[0] *= 2;
}
double *compute_copying(const double *input) {
double *output = malloc(sizeof *output * N);
if (output == NULL)
return NULL;
memcpy(output, input, sizeof *output * N);
compute_inplace(output);
return output;
}
Note that the copying function takes its argument as a pointer to const, which helps if you accidentally pass a read-only memory area to it.
Upvotes: 1
Reputation: 43
Other possible solution could be to have following definition:-
double* my_function(double* input, bool alloc)
{
double* output = input;
if(alloc)
{
//allocate new memory
double* output = ( double*)malloc(...);
}
//else work with input memory
//do modifications here
return output;
}
Upvotes: 0