2011-03-21 172 views
9

我想創建一個從字符串派生的新整數數組。例如:從函數返回數組/指針

char x[] = "12334 23845 32084"; 

int y[] = { 12334, 23845, 32084 }; 

我無法理解如何從一個函數返回一個數組(我的理解是不可能的)。

我最初試圖:

/* Convert string of integers into int array. */ 
int * splitString(char string[], int n) 
{ 
    int newArray[n]; 

    // CODE 

    return (newArray); 
} 

int main(void) 
{ 
    int x[n] = splitString(string, n); 

    return (0); 
} 

後來我才知道,你不能做到這一點。

指針如何在函數中工作?

謝謝。

回答

15

通常,您需要調用者傳入結果數組。

void splitString(const char string[], int result[], int n) { 
    //.... 
} 

這是有利的,因爲無論他們想要的主叫方可以分配內存。

+0

這是首選的方法。在99%的情況下,從函數返回任何類型的指針都沒有意義。 – Lundin 2011-03-21 14:40:34

+5

對。正如其他答案中提到的那樣,你可以在你的函數中使用'malloc(n * sizeof(int))'來分配內存並返回該指針,但是你總是必須記住最終'釋放'內存。由於'malloc'隱藏在一個不同抽象層次的函數中,因此你很容易忘記。因此,最好分配內存並將指針傳遞給函數,使用結果,然後釋放內存,以便可以輕鬆地將「malloc」與「free」匹配起來。 – JCooper 2011-03-21 14:56:48

+0

@JCooper:調用者也可以從池中,堆棧中或其他任何他想要放置的內存中分配內存,但函數不能。 – Puppy 2011-03-21 15:24:53

5
int * splitString(char string[], int n) 
{ 
    int newArray[n]; 
    return (newArray); 
} 

這很糟糕!當函數返回時,函數局部的數組被破壞。你會被遺漏一個懸掛指針,並使用它會調用未定義的行爲。

您不能從函數返回數組。你能做的最好的是

int * splitString(char string[], int n) 
{ 
    int *newArray = malloc(n*sizeof(int)); // the array gets allocated on the heap rather than on the stack(1) 
    // Code 
    return (newArray); 
} 

不要忘記釋放分配的內存。 (1)請注意,標準沒有使用/定義術語堆棧或堆本身。

+0

是的,我知道這件事情。我在網上搜索了一些關於如何正確實現的例子,但是我找不到任何東西。 – Garee 2011-03-21 14:14:58

+0

@prasoonSaurav,所以你已經提到過,函數的newArray會被銷燬,所以我們返回指針。指針通常存儲內存的地址,那麼如果我們返回包含我們在函數內創建的內存地址的指針,那麼內存也會被銷燬?你能解釋我,我找不到答案 – 2018-02-25 19:03:06

+0

好吧,我在這裏得到了答案https://stackoverflow.com/a/11656585/4146319 – 2018-02-26 17:09:31

12

問題是你正在返回一個指向棧上的東西的指針。您需要創建在堆上陣列,然後釋放它,當你完成:

int * splitString(char string[], int n) 
{ 
    int *newArray = malloc(sizeof(int) * n); 

    // CODE 

    return (newArray); 
} 

int main(void) 
{ 
    int *x = splitString(string, n); 

    // use it 

    free(x); 

    return (0); 
} 
3

而不是return (newArray)返回一個數組,你指針返回newArray的第一要素。

問題是你是以錯誤的方式分配數組。如果使用int newArray[n]實例化內存,則會在當前堆棧幀上分配內存。只要你的函數返回,那個內存就會被釋放,而且數組中的任何東西都是垃圾。相反,做到以下幾點:

int *newArray = malloc(n * sizeof(int)); 
// etc. 
return newArray 

使用malloc,你在堆上,它會活過當前堆棧幀的末尾分配內存。當你完成後,請記得在你的程序的某個地方使用free(newArray)

1

當然這是可能的。 這是我更喜歡的方式: int func(int** results)

函數返回results中元素的個數。 results是一個指向int數組的指針。

2

你可以在一個結構中包裝數組,然後返回結構的一個實例。 我提到這是完整的,它不是你想要做的事情,因爲它很醜並且有更好的選擇。

#include <stdio.h> 

struct retval 
{ 
    int a[10]; 
}; 

struct retval test() 
{ 
    struct retval v = {{1, 5, 6}}; 
    return v; 
} 

int main() 
{ 
    struct retval data = test(); 
    printf("%d %d\n", data.a[1], data.a[2]); 
} 
+0

只是想知道,這是如何工作的?不是「v.a」指向堆棧「測試」位置的指針嗎? 「結構retval數據=測試();」導致數組的深層副本? – Pradyumna 2015-06-12 08:18:46

2

我會去做這樣

/* Convert string of integers into int array. */ 
void splitString(char string[], int *out_arr, int n) 
{ 

    // code that fills each cell of out_arr 

} 

int main(void) 
{ 
    int x[n]; 
    splitString(string,(int *)x, n); 

    return (0); 
}