Reputation: 2760
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
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
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