Возврат массивов / указателей из функции
Я пытаюсь создать новый целочисленный массив, который является производным от строки символов. Например :
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 );
}
позже я узнал, что вы не можете сделать это.
как работают указатели в отношении функций?
спасибо.
7 ответов
обычно требуется, чтобы вызывающий объект передал массив результатов.
void splitString( const char string[], int result[], int n) {
//....
}
это выгодно, потому что вызывающий может выделить эту память, где они хотят.
проблема вы возвращаете указатель на стек. Вам нужно создать массив в куче, а затем освободить его, когда вы закончите:
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 );
}
int * splitString( char string[], int n )
{
int newArray[n];
return ( newArray );
}
Это очень плохо! Массив newArray
local для функции разрушается, когда функция возвращается. Вы останетесь с болтающимся указателем, и его использование вызовет неопределенное поведение.
вы не можете вернуть массив из функции. Лучшее, что вы можете сделать, это
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) Обратите внимание, что стандарт не использует/не определяет термин "стек" или "куча" как таковой.
вместо того, чтобы возвращать массив с return (newArray)
возвращается указатель к первому элементу newArray.
проблема в том, что вы неправильно выделяете массив. Если вы создадите его с помощью int newArray[n]
память выделяется в текущем кадре стека. Эта память будет освобождена, как только ваша функция вернется, и все, что было в массиве, будет мусором. Вместо этого, сделайте следующее:
int *newArray = malloc(n * sizeof(int));
// etc.
return newArray
С помощью malloc
, вы выделяете память о куча, где она будет выживать после окончания текущего кадра стека. Просто не забудьте free(newArray)
где-то в вашей программе, Когда вы закончите.
вы можете обернуть массив в структуру, а затем вернуть экземпляр структуры. Я упоминаю об этом для полноты, это не то, что вы хотели бы сделать, поскольку это уродливо, и есть лучшие альтернативы.
#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]);
}
Я бы пошел об этом таким образом
/* 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 );
}
конечно, это возможно.
Это то, что я предпочитаю.:
int func(int** results)
функция возвращает количество элементов в results
. results
указатель на массив int.