KindaTechy
KindaTechy

Reputation: 1173

Getting the return address of a function in C

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

Answers (2)

Roland Illig
Roland Illig

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

MGpro
MGpro

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

Related Questions