web-dev-qa-db-ja.com

関数から配列/ポインタを返す

文字列から派生した新しい整数配列を作成しようとしています。例えば ​​:

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 );
}

私は後でこれを行うことができないことを学びました。

関数に関してポインタはどのように機能しますか?

ありがとうございました。

12
Garee

通常、呼び出し元は結果配列を渡す必要があります。

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

呼び出し側はどこにでもメモリを割り当てることができるため、これは有利です。

19
Puppy

問題は、スタック上の何かへのポインターを返すことです。ヒープ上に配列を作成し、完了したらそれを解放する必要があります。

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 );
}
14
Brian Roach
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)この規格では、スタックまたはヒープという用語をそのように使用/定義していないことに注意してください。

5
Prasoon Saurav

return (newArray)で配列を返すのではなく、pointerをnewArrayの最初の要素に返します。

問題は、配列を間違った方法で割り当てていることです。 _int newArray[n]_でインスタンス化すると、メモリは現在のスタックフレームに割り当てられます。そのメモリは関数が戻るとすぐに解放され、配列にあったものはすべてガベージになります。代わりに、以下を実行します。

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

mallocを使用すると、現在のスタックフレームの終わりを超えて存続するヒープにメモリを割り当てます。完了したら、プログラムのどこかにfree(newArray)を覚えておいてください。

3
Jacob

配列を構造体でラップしてから、構造体のインスタンスを返すことができます。完全を期すためにこれについて言及します。醜くてより良い代替手段があるので、あなたがしたいことではありません。

#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]);
}
2
jcoder

私はそれについてこのように行きます

/* 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
TanyaV

もちろん可能です。これは私が好む方法です:int func(int** results)

関数はresultsの要素数を返します。 resultsは、int配列へのポインターです。

0
Dr McKay