C:voidを介して戻る関数*
-
10-07-2019 - |
質問
Javaから来ると、以下の戻り値を許可するVoidの使用に混乱しています。
void *emalloc(size_t s) {
void *result = malloc(s);
if (NULL == result) {
fprintf(stderr, "MEMORY ALLOCATION FAILURE\n");
exit( EXIT_FAILURE );
}
return result;
}
これは、割り当てられたメモリのチャックへのポインタを返しますか?
解決
はい、そうです。 void *ポインターは、基本的にメモリアドレスへの汎用ポインターであり、通常は実際に必要な型に型キャストできます。
他のヒント
あなたの質問は、関数の戻り値の型を読み間違えていることを示しています。次の間に大きな違いがあります:
void foo( void ) {}
and
void *bar( void ) {}
foo()は引数を取らず、値を返しませんが、bar()は引数を取らず、汎用ポインターを返します。 Cでは、キーワードvoidは汎用ポインターを示すために使用され、タイプvoid *のオブジェクトは、情報を失うことなく他のオブジェクトポインタータイプに変換できます。
はい、この関数は指定されたサイズの割り当てられたメモリへのポインタを返します。 mallocでは、ポインターを返すことが保証されているという意味で異なります。失敗すると、アプリケーションを終了します。
はい。 void *
は何かへのポインタを意味しますが、特定のタイプではありません。
voidは本質的に型がないことを意味するため、void * pがある場合、 pは何かへのポインタですが、何を言っていないのですか。
ポインターなしのvoidは何もないため、void foo(void)は引数をとらず、何も返さない関数です。
そして、はい、mallocはメモリのチャンクへのポインタを返します。mallocはそのメモリの型を知らないか気にしません。そのため、戻り型はvoid *
です。 Javaでは、ポインター演算はありません。これがあなたが求めていることだと思います。たとえば、 malloc
が int
int* malloc(size_t size)
{
//
}
ポインタを受け取る可能性があります。これは基本的には array
へのポインタです。次に、通常の配列のようにインデックスを作成します。
int* arr = malloc(10 * sizeof(int)); // 10 contiguous int(s).
問題は、 C
に関数のオーバーロードがないことです。したがって、汎用の malloc
を記述する方法を見つける必要があります。そうしないと、タイプごとに異なる malloc
になってしまいます。解決策は、必要なバイト数を送信することです。その後、好きなようにインデックスを作成できます。これにより、柔軟性が高まり、すべてのソリューションに対応できます。
int* i = (int*)malloc(10 * sizeof(int)); // 40 bytes if int = 4 bytes
char* c = (char*)malloc(10 * sizeof(char)); // 10 bytes if char = 1 byte
int thirdElement = i[3]; // third element. 12 bytes away from (*i)
char secondElement = c[2]; // second element. 2 bytes away from (*c)
つまり、全体的な考え方は、 malloc
から取得したメモリをどのようにインデックス付けしてもかまわないということです。しなければならないことは、新しく作成された配列のタイプを指定して、適切にインデックスを付けることです。 void *
は、これがインデックス方法を指定していないメモリ内に配置するポインタであることを意味します。