這個問題在這里已經有了答案: 未定義、未指定和實作定義的行為 (9 個回答) 如何使用指標從不同的函式訪問區域變數? (10 個回答) 昨天關閉。
#include <stdio.h>
int *sum_returning_pointer(int *x, int *y)
{
// Call be reference
int z = (*x) (*y);
return &z;
}
void main(int *argc, char *argv[])
{
int a = 1, b = 2;
int *p = sum_returning_pointer(&a, &b);
printf("Sum = %d\n", *p);
}
使用上面的函式,我試圖將作為被呼叫函式的參考傳遞的兩個數字相加,并回傳指向存盤 sum 的變數的指標。但我收到奇怪的錯誤提示。
Error has occured.
Segmentation Fault.
這個錯誤是什么意思?我怎樣才能找到解決方案?為什么會出現這個錯誤?
uj5u.com熱心網友回復:
在主函式中 z 不可訪問,這就是它顯示未定義行為的原因。您可以將 z 宣告為全域變數,例如
#include <stdio.h>
int z =0;
int * sum_returning_pointer(int *x, int *y)
{
// Call be reference
z = (*x) (*y);
return &z;
}
void main(int *argc, char *argv[])
{
int a = 1, b = 2;
int *p = sum_returning_pointer(&a, &b);
printf("Sum = %d\n", *p);
}
uj5u.com熱心網友回復:
問題不在于如何取消參考,而在于如何確保指標有效。在您的代碼中,回傳了區域變數的地址。當程式從函式回傳時,此變數的生命周期結束。在呼叫Undefined Behavior之后取消參考此指標。
請注意,通常像這樣的小物件int應該按值回傳。
從函式回傳指向結果的指標有 3 種通用策略。
- (IMO,最好的)讓呼叫者處理生命周期。
int *foo(const int *x, const int *y, int *z) {
*z = *x *y;
return z;
}
用法:
int x = 1, y = 2, z;
int *res = foo(&x, &y, &z);
- 使用動態存盤
int *foo(const int *x, const int *y) {
int *z = malloc(sizeof *z);
if (!z) {
// complain
return NULL;
}
*z = *x *y;
return z;
}
這種解決方案往往非常緩慢且容易出錯,因為呼叫者負責釋放結果。
- 使用靜態。
int *foo(const int *x, const int *y) {
static int z;
z = *x *y;
return &z;
}
效果很好,因為靜態變數的生命周期延伸到程式的整個執行程序。
主要問題是指標指向的物件會隨著每次呼叫而改變foo。這對于多執行緒應用程式尤其危險。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/334847.html
