Возвращение массивов / указателей из функции - PullRequest
11 голосов
/ 21 марта 2011

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

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 ]

19 голосов
/ 21 марта 2011

Обычно требуется, чтобы вызывающая сторона передавала массив результатов.

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

Это выгодно, поскольку вызывающая сторона может выделять эту память где угодно.

13 голосов
/ 21 марта 2011

Проблема в том, что вы возвращаете указатель на что-то в стеке.Вам нужно создать свой массив в куче, а затем освободить его, когда вы закончите:

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 );
}
5 голосов
/ 21 марта 2011
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) Обратите внимание, что стандарт не использует / не определяет термин стек или кучу какнапример.

3 голосов
/ 21 марта 2011

Вместо того, чтобы возвращать массив с return (newArray), вы возвращаете указатель на первый элемент newArray.

Проблема в том, что вы размещаете массив неверным образом.Если вы создаете его с помощью int newArray[n], память выделяется в текущем кадре стека.Эта память будет освобождена, как только ваша функция вернется, и все, что было в массиве, будет мусором.Вместо этого выполните следующее:

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

Используя malloc, вы выделяете память в куче, где она будет сохраняться после конца текущего кадра стека.Просто не забудьте free(newArray) где-нибудь в вашей программе, когда вы закончите.

2 голосов
/ 11 января 2017

Я бы пошел по этому пути

/* 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 );
}
2 голосов
/ 06 марта 2013

Вы можете заключить массив в структуру, а затем вернуть экземпляр структуры.Я упоминаю это для полноты, это не совсем то, что вы хотели бы сделать, потому что это уродливо и есть лучшие альтернативы.

#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 голосов
/ 21 марта 2011

Конечно, это возможно.Я предпочитаю так: int func(int** results)

Функция возвращает количество элементов в results.results - указатель на массив int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...