文字列から派生した新しい整数配列を作成しようとしています。例えば :
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 );
}
私は後でこれを行うことができないことを学びました。
関数に関してポインタはどのように機能しますか?
ありがとうございました。
通常、呼び出し元は結果配列を渡す必要があります。
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
は、関数が戻るときに破棄されます。宙ぶらりんのポインタがなくなり、それを使用すると未定義の動作が発生します。
関数から配列を返すことはできません。あなたができる最高のことは
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)
で配列を返すのではなく、pointerを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配列へのポインターです。