bergercookie
bergercookie

Reputation: 2760

Getting the address of function return arguement in C

Having read the chapter about sttructures from "The C programming Language book" I tried the following code. The goal is to have an array of pointer initialized with some specific value for all its points.

#include <stdio.h>

#define MAXPOINTS 1000

struct point {
    int x;
    int y;
};

struct point makepoint(int x, int y);

int main(int argc, const char *argv[])
{
    int i;
    int number1 = 5, number2 = 10;
    struct point *points[1000];

    for (i=0; i< MAXPOINTS; i++) {
        points[i]  = &(makepoint(number1, number2));
    }
}

struct point makepoint(int x, int y) {
    struct point my_point;
    my_point.x = x;
    my_point.y = y;
    return my_point;
}

The error generated after running the above code is the following:

test_something.c:18:22: error: cannot take the address of an rvalue of type 'struct point'

Why does this happen since the makepoint function does return a valid point object?

Thanks in advance,

Upvotes: 2

Views: 226

Answers (2)

whoan
whoan

Reputation: 8521

You are returning a temporary copy of a point and take his address is not a good idea. Try this:

struct point* makepoint(int x, int y);

int main(int argc, const char *argv[]) {
    int i;
    int number1 = 5, number2 = 10;
    struct point* points[MAXPOINTS];

    for (i=0; i< MAXPOINTS; i++)
        points[i]  = makepoint(number1, number2);

    for (i=0; i< MAXPOINTS; i++)
        free(points[i]);
    return 0;
}

struct point* makepoint(int x, int y) {
    struct point* my_point = malloc(sizeof(struct point));
    my_point->x = x;
    my_point->y = y;
    return my_point;
}

Anyway, in your code:

struct point *points[10];

for (i=0; i< MAXPOINTS; i++) {
    points[i]  = &(makepoint(number1, number2));
}

...you have an array of 10 pointers and you're trying to assign 1000 pointers (MAXPOINTS).

Upvotes: 2

Kninnug
Kninnug

Reputation: 8053

You cannot take the address of a value, only of a variable. This is because values don't necessarily need to live in (addressable) memory. For example: the return value of a function is (usually) passed via a register, and you cannot take the address of a register(-variable).

You could instead change your makepoint function to take a pointer to a struct point and fill it in:

struct point makepoint(struct point * in, int x, int y){
    in->x = x;
    in->y = y;
    return *in;
}

Note that the return value isn't strictly necessary, but kept for 'backward compatability'.

Upvotes: 2

Related Questions