簡體   English   中英

從函數(C)返回數組

[英]Returning array from function (C)

我對C編程非常陌生,並且正在閱讀一些教程。 讓我感到困擾的一件事是返回指向數組的指針。 我已從https://www.tutorialspoint.com/cprogramming/c_return_arrays_from_function.htm中刪減了該示例,以最好地說明我的觀點。

#include <stdio.h>

int * getRandom( ) {

   static int  r[10];
   int i;

   for ( i = 0; i < 10; ++i) {
      r[i] = i;
      printf( "r[%d] = %d\n", i, r[i]);
   }
   return r;
}

int main () {
   int *p;
   int i;
   p = getRandom();
   for ( i = 0; i < 10; i++ ) {
      printf( "*(p + %d) : %d\n", i, *(p + i));
   }
   return 0;
}

正如人們所料,

r[0] = 0
r[1] = 1
r[2] = 2
r[3] = 3
r[4] = 4
r[5] = 5
r[6] = 6
r[7] = 7
r[8] = 8
r[9] = 9
*(p + 0) : 0
*(p + 1) : 1
*(p + 2) : 2
*(p + 3) : 3
*(p + 4) : 4
*(p + 5) : 5
*(p + 6) : 6
*(p + 7) : 7
*(p + 8) : 8
*(p + 9) : 9

但是當你改變

   static int  r[10];

   int  r[10];

而是打印

r[0] = 0
r[1] = 1
r[2] = 2
r[3] = 3
r[4] = 4
r[5] = 5
r[6] = 6
r[7] = 7
r[8] = 8
r[9] = 9
*(p + 0) : 0
*(p + 1) : 1980517315
*(p + 2) : -1164399724
*(p + 3) : 4199040
*(p + 4) : 4199040
*(p + 5) : 2285568
*(p + 6) : 19
*(p + 7) : 6356668
*(p + 8) : 8
*(p + 9) : 6356940

我不知道為什么 我唯一能想到的是由於某種原因,編譯器將數組單元讀取為不同的數據類型,但是我懷疑這是正確的。

static關鍵字用於在下次調用中“記住” r的值。 如果將其刪除,則在函數返回時將清除分配給r的內存,因此您只是在返回垃圾。

當您有static int r[10]; ,用於存儲數組的內存在編譯時分配,並且一切都按預期工作。

當您使用int r[10] ,您將在運行時堆棧幀上分配數組,該數組在函數調用返回時變為無效,然后被下一個函數調用覆蓋,因此您會看到垃圾。

原因是,當您在沒有靜態數組聲明的情況下調用getRandom() ,一旦getRandom()函數返回,該數組就會超出范圍。 這意味着您的指針可能不再“指向” r,因為r實際上已被丟棄。

為了正確地從getRandom()返回,您需要使用malloc動態分配內存,例如:

int * getRandom( ) {
  int *r = NULL;
  r = malloc(sizeof(int) * 10); /* Create room for 10 integers*/
  if (r == NULL) {
    printf("Error: Could not allocate space\n");
    return NULL;
  }
  int i;
  for ( i = 0; i < 10; ++i) {
    r[i] = i;
    printf( "r[%d] = %d\n", i, r[i]);
  }  
  return r; /* Returns a pointer to r*/
}

int main () {
  int *p;
  int i;
   p = getRandom();
   if (p == NULL) {
     /*Error state*/
     return 1;
   }
   for ( i = 0; i < 10; i++ ) {
     printf( "*(p + %d) : %d\n", i, *(p + i));
   }
   free(p); /* Free the memory we allocated*/
  return 0;
}

請注意,我們必須如何free分配的內存(否則會發生內存泄漏)。 還要注意,我們必須處理NULL情況,在這種情況下我們無法分配必要的內存。

除少數情況外,表達式中的數組始終會衰減到其第一個元素的地址。
該指針是函數返回的值。
數組本身作為內存中的對象,通常會在函數執行完成后死亡。
因此,不能保證函數返回的指針所指向的內存地址會保留該數組,而可能會有垃圾。
static聲明保留了數組對象,但是您的函數仍然返回了指向數組開頭而不是數組本身的指針。
不好的做法是將指針返回到函數的內部static對象,因為您允許函數的任何用戶以不可預測的方式從函數外部更改數組的值。
如果要返回一個完整的數組作為值,則也許應該以這種方式定義一個包含數組字段的struct類型:

  typedef struct {  int sub[10]; } wrappedarray_t;
  wrappedarray_t getRandom(void) {
         wrappedarray_t r;
         // sentences....
         return r;
   }
   wrappedarray_t p = getRandom();
   printf("0th element: %d\n", p.sub[0]);

因為您使用的是本地分配的數據; 一旦程序超出范圍,則保存到其中的所有數據將被丟棄,並返回垃圾值。

在這種情況下,您可以做兩件事:

要么malloc()一個指針數組,要么使用靜態數組並返回其中之一。

您可以做的另一種選擇是在函數參數中放置一個數組緩沖區,以便將數據復制到該緩沖區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM