2017-04-09 37 views
0

我很抱歉這個愚蠢的問題,但我是C和指針的新手。
我寫了一個簡單的程序,找到最大的一個整數集的:使用指針和數組時奇怪的結果

#include <stdio.h> 
#define MAX 10 

int* getIntegers() { 
    int a[MAX]; 
    int i = 0; 
    while (i < MAX) { 
    int n; 
    printf("Insert an integer: "); 
    scanf("%d", &n); 
    a[i] = n; 
    i++; 
    } 
    int *p = a; 
    return p; 
} 

int findMax(int *s) { 
    int max = -1000000; 
    for (int i = 0; i < MAX; i++) { 
    if (s[i] > max) { 
     max = s[i]; 
    } 
    } 
    return max; 
} 

int main() { 
    int *p = getIntegers(); 
    int max = findMax(p); 
    printf("Max value: %d\n", max); 
    return 0; 
} 

這個程序似乎工作,但如果我從10更改MAX值到另一個號碼停止工作,它返回另一個作爲輸入我沒有通過的大價值。這個問題似乎是當我調用函數findMax(int *array)時,因爲如果我打印由函數getIntegers()創建的數組,一切似乎都可以。有誰能夠幫助我?

+1

誰告訴你從函數'return p;'返回一個棧分配數組,你可以使數組成爲靜態的'static int a [MAX];'但是b你避免它,並使用malloc代替。 –

+2

在'getIntegers'中,您將返回一個指向局部變量的指針。 –

+0

請不要使用'scanf'。使用'fgets'或'gets_s'然後'sscanf'。並檢查返回值。 –

回答

2

根據相對於與自動存儲持續時間

6對象對於這樣一個對象,該對象不具有可變長度數組類型的C標準(對象6.2.4存儲的持續時間), 其壽命延伸從進入與它相關聯 直到該塊的執行以任何方式

在該功能結束塊

int* getIntegers() { 
    int a[MAX]; 
    // ... 
    int *p = a; 
    return p; 
} 

數組a具有自動存儲持續時間,並且在退出該功能後其壽命結束。所以指針p將具有無效值,因此程序具有未定義的行爲。

考慮到程序中存在拼寫錯誤。聲明的功能名稱類似getIntegers,但主內部使用另一個名稱getTenIntegers

int main() { 
    int *p = getTenIntegers(); 
    //... 

您需要動態分配所需大小的數組,並在程序結束時釋放它。

功能findMax不依賴魔術值MAX更好。所以你應該傳遞函數的第二個值 - 數組的大小。另外,名稱MAX可以是宏名稱,所以最好使用其他名稱而不是MAX

在C函數main無參數應聲明如下

int main(void) 

這裏顯示的程序如何看

#include <stdlib.h> 
#include <stdio.h> 

#define SIZE 10 

int * getIntegers(size_t n) 
{ 
    int *a = malloc(n * sizeof(int)); 

    if (a) 
    { 
     for (size_t i = 0; i < n; i++) 
     { 
      int value; 
      printf("Insert an integer: "); 
      scanf("%d", &value); 
      a[i] = value; 
     } 
    }  

    return a; 
} 

size_t findMax(const int *a, size_t n) 
{ 
    size_t max = 0; 

    for (size_t i = 1; i < n; i++) 
    { 
     if (a[max] < a[i]) max = i; 
    } 

    return max; 
} 

int main(void) 
{ 
    int *p = getIntegers(SIZE); 

    if (p) 
    { 
     printf("Max value: %d\n", p[ findMax(p, SIZE) ]); 
    } 

    free(p); 

    return 0; 
} 

它的輸出可能是

Insert an integer: 1 
Insert an integer: 3 
Insert an integer: 9 
Insert an integer: 2 
Insert an integer: 0 
Insert an integer: 8 
Insert an integer: 7 
Insert an integer: 5 
Insert an integer: 6 
Insert an integer: 4 
Max value: 9 
2

這是因爲數組a(在getIntegers中定義)被分配到堆棧上,因此這意味着您將地址返回到堆棧上的已分配內存。

一旦你的函數getIntegers完成,內存空閒,你指向無效的內存。