2014-10-05 100 views
2

阅读“C编程语言手册”中关于结构的章节后,我尝试了下面的代码。目标是让一个指针数组初始化为其所有点的某个特定值。获取函数返回参数的地址C

#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; 
} 

运行上面的代码后,所产生的错误是:

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

为什么会发生这种情况,因为makepoint功能并返回一个有效点的对象?

由于提前,

+0

请注意,即使这是合法的,它也会导致UB,因为从函数返回的值在当前语句后不再存在 – 2014-11-01 01:01:43

回答

2

您正在退回临时复制的一个点,并采取他的地址是不是一个好主意。 试试这个:

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; 
} 

不管怎样,在你的代码:

struct point *points[10]; 

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

...你有10个指针数组,你想分配1000个指针(MAXPOINTS)。

+0

看起来像这样的答案,上面的答案可以用比我的更好的方式解释:-) 。还有,关于数组大小的好消息。 – 2014-10-05 15:24:59

2

你不能只是一个变量的值的地址。这是因为值不一定需要居住在(可寻址的)存储器中。例如:函数的返回值(通常)是通过寄存器传递的,并且不能取寄存器的地址(-variable)。

你可以代替更改makepoint函数取一个指向struct point并填写好:

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

注意,返回值是不是绝对必要的,但保持“向后兼容性”。