2011-03-21 131 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); 
}