C 从函数返回数组/指针
我正在尝试创建一个新的整数数组,它是从字符串派生的。例如:C 从函数返回数组/指针,c,arrays,function,pointers,C,Arrays,Function,Pointers,我正在尝试创建一个新的整数数组,它是从字符串派生的。例如: 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];
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 );
}
我后来才知道你不能这样做
指针在函数方面是如何工作的
多谢各位
int * splitString( char string[], int n )
{
int newArray[n];
return ( newArray );
}
这太糟糕了!函数返回时,函数本地的数组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) 请注意,该标准没有使用/定义堆栈或堆这一术语。问题是您正在返回指向堆栈上某个内容的指针。您需要在堆上创建数组,然后在完成后释放它:
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 );
}
与使用
return(newArray)
返回数组不同,您返回指向newArray的第一个元素的指针
问题是您以错误的方式分配阵列。如果使用intnewarray[n]
实例化它,则会在当前堆栈帧上分配内存。该内存将在函数返回时立即释放,数组中的任何内容都将成为垃圾。相反,请执行以下操作:
int *newArray = malloc(n * sizeof(int));
// etc.
return newArray
通过使用malloc
,可以在堆上分配内存,它将在堆中生存到当前堆栈帧的末尾。只要记住,当你完成时,在程序中的某个地方释放(newArray)。当然这是可能的。
这是我喜欢的方式:
int func(int**results)
函数返回
结果中的元素数results
是指向int数组的指针。通常,您需要调用者传入结果数组
void splitString( const char string[], int result[], int n) {
//....
}
这是有利的,因为调用者可以在任何他们想要的地方分配内存。您可以在结构中包装一个数组,然后返回该结构的实例。
我提到这一点是为了完整性,这并不是你真正想做的事情,因为它很难看,而且还有更好的选择
#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]);
}
#包括
结构检索
{
INTA[10];
};
结构检索测试()
{
struct retval v={1,5,6};
返回v;
}
int main()
{
struct retval data=test();
printf(“%d%d\n”,data.a[1],data.a[2]);
}
我看到的主要问题是试图返回您在堆栈上分配的内存,一旦在reutrns中分配了该内存的函数(在本例中是您的splitString),该内存将变得无效。您可以做的是在调用者中分配内存,并将指向数组开头的指针传递给函数
/* 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 );
}
是的,我现在意识到了。我在网上搜索了一些关于如何正确实现的例子,但是我找不到任何东西。@prasoonSaurav,正如您所提到的,函数的本地newArray被破坏了,所以我们返回指针。指针通常存储内存地址,若我们返回包含我们在函数中创建的内存地址的指针,那个么内存也会被破坏,对吗?你能解释一下吗?我找不到答案。这是首选的方法。在99%的情况下,从function.Right返回任何类型的指针都没有意义。正如在其他答案中提到的,您可以在函数中使用malloc(n*sizeof(int))
来分配内存并返回该指针,但是您必须始终记住最终释放
内存。由于malloc
隐藏在不同抽象级别的函数中,因此您很容易忘记。因此,最好分配内存并将指针传递给函数,使用结果,然后释放内存,这样您就可以轻松地将malloc
s与free
s进行匹配。@JCooper:调用方还可以从池中、堆栈外或任何他想放置的地方分配内存,但是函数不能。您的语法不正确。[]
位于参数名称之后。只是想知道,这是如何工作的?“v.a”不是指向“test”堆栈上某个位置的指针吗?“struct retval data=test();”是否会生成数组的深度副本?不需要强制转换