Возврат массивов / указателей из функции

Я пытаюсь создать новый целочисленный массив, который является производным от строки символов. Например :

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.