2014-10-05 85 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; 
} 

注意,返回值是不是絕對必要的,但保持「向後兼容性」。